sapling-dialogue 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/sapling +5 -0
- data/lib/sapling.rb +43 -0
- data/lib/sapling/dialogue.rb +110 -0
- data/lib/sapling/gardner.rb +48 -0
- data/lib/sapling/planter.rb +210 -0
- data/lib/sapling/utility.rb +58 -0
- metadata +50 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 5aaa32f64d5d1e66ff4d8418c48067f2e8a4c283
|
|
4
|
+
data.tar.gz: ddd847cc2912019b12de02680dd35282d7108be3
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 798eb921d6a9b8774de8c0353a38b4e7201aebeee83badb67047c3e9f14f2d82886b470f797f1709f977d88c17584299ffbd12f23db74ed1597d5b7434c6c43e
|
|
7
|
+
data.tar.gz: fb7ac1db708b798f8599d758ada08c7176fcd94a0ef94955ff3871793ce1b0d0776e00def90f255a94afd465df4e0f4b333983f43f3a0c110a0d5be61025589d
|
data/bin/sapling
ADDED
data/lib/sapling.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'thor'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
|
|
6
|
+
Dir[File.join(__dir__, 'sapling', '*.rb')].each { |file| require file }
|
|
7
|
+
|
|
8
|
+
# The main Sapling interface.
|
|
9
|
+
class Sapling < Thor
|
|
10
|
+
desc 'read TREE', 'Load and traverse the TREE'
|
|
11
|
+
def read(tree)
|
|
12
|
+
exit unless verify_tree(tree)
|
|
13
|
+
puts 'Welcome to Sapling, a Dialogue Tree Utility.'
|
|
14
|
+
speaker = Dialogue::Speaker.new(YAML.load_file(tree), false)
|
|
15
|
+
speaker.conversation
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'edit TREE', 'Edit a new or existing TREE'
|
|
19
|
+
def edit(tree = '')
|
|
20
|
+
puts 'Welcome to Sapling, a Dialogue Tree Utility.'
|
|
21
|
+
if !tree.empty?
|
|
22
|
+
puts "Loading tree: #{tree}"
|
|
23
|
+
exit unless verify_tree(tree)
|
|
24
|
+
gardner = Planter::Spade.new(YAML.load_file(tree, false))
|
|
25
|
+
else
|
|
26
|
+
puts 'Creating a new tree!'
|
|
27
|
+
gardner = Planter::Spade.new(SKELETON_TREE)
|
|
28
|
+
end
|
|
29
|
+
gardner.plant
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
desc 'serve TREE', 'Load TREE in a web-based interface'
|
|
33
|
+
def serve(tree)
|
|
34
|
+
exit unless verify_tree(tree)
|
|
35
|
+
puts 'Sinatra will be cool.'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
desc 'export TREE', 'Save a portable HTML version of TREE'
|
|
39
|
+
def export(tree)
|
|
40
|
+
exit unless verify_tree(tree)
|
|
41
|
+
puts 'Cool feature, bro!'
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require_relative './gardner'
|
|
2
|
+
|
|
3
|
+
# Dialogue is the module for traversing an existing tree.
|
|
4
|
+
module Dialogue
|
|
5
|
+
|
|
6
|
+
# Format and display the trunk
|
|
7
|
+
#
|
|
8
|
+
# @param trunk [Hash] The trunk hash
|
|
9
|
+
# @param debug [Boolean] The status of showing debug information
|
|
10
|
+
def self.display_trunk(trunk, debug=false)
|
|
11
|
+
40.times { print "-" }
|
|
12
|
+
puts "\n[ Trunk ]\n" if debug
|
|
13
|
+
puts "\n#{trunk["trunk"]}"
|
|
14
|
+
40.times { print "-" }
|
|
15
|
+
puts "\n"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Format and display a branch and the options
|
|
19
|
+
#
|
|
20
|
+
# @param branch [Hash] A branch data set
|
|
21
|
+
# @param branch_no [Integer] The branch number
|
|
22
|
+
# @param debug [Boolean] Status of showing debug information
|
|
23
|
+
def self.display_branch(branch, branch_no, debug=false)
|
|
24
|
+
puts "\n[ Branch: #{branch_no} ]" if debug
|
|
25
|
+
puts "\n#{branch["desc"]}\n\n"
|
|
26
|
+
|
|
27
|
+
branch["options"].each_pair do |k,v|
|
|
28
|
+
puts "\t#{k}: #{v.keys[0]}"
|
|
29
|
+
puts "\t\t[ Goes to branch #{v.values[0]} ]\n" if debug
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Speaker holds the functionality for going through a dialogue tree.
|
|
34
|
+
class Speaker
|
|
35
|
+
# The file, which should be a dialogue tree YAML file.
|
|
36
|
+
attr_accessor :file
|
|
37
|
+
# Status of verbose/debug mode. True = on; false = off.
|
|
38
|
+
attr_accessor :debug
|
|
39
|
+
|
|
40
|
+
def initialize(file="", debug=false)
|
|
41
|
+
@file = file
|
|
42
|
+
@debug = debug
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Conversation handles navigating the tree, until the option to end is
|
|
46
|
+
# reached.
|
|
47
|
+
def conversation()
|
|
48
|
+
tree = Gardner.prune_trunk(@file)
|
|
49
|
+
|
|
50
|
+
Dialogue.display_trunk(tree[0], false)
|
|
51
|
+
branches = Gardner.prune_branches(tree[1])
|
|
52
|
+
|
|
53
|
+
next_branch = 1
|
|
54
|
+
until next_branch == 0 do
|
|
55
|
+
next_branch = talk(branches[next_branch], next_branch)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
puts "\n#{branches[0]["desc"]}"
|
|
59
|
+
exit
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Talk displays a branch, the options, and prompts for a response.
|
|
63
|
+
#
|
|
64
|
+
# @param branch [Hash] A branch data set
|
|
65
|
+
# @param branch_no [Integer] The branch number
|
|
66
|
+
# @return [Integer] The number of the next branch
|
|
67
|
+
def talk(branch, branch_no)
|
|
68
|
+
# If there are no options on this branch, we assume it's a terminal
|
|
69
|
+
# branch. Return 0, and end the program.
|
|
70
|
+
if branch["options"].empty?
|
|
71
|
+
puts "\n#{branch["desc"]}\n\n"
|
|
72
|
+
return 0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
Dialogue.display_branch(branch, branch_no, @debug)
|
|
76
|
+
|
|
77
|
+
response = get_response(branch)
|
|
78
|
+
|
|
79
|
+
unless response == 0
|
|
80
|
+
puts "\n"
|
|
81
|
+
10.times { print "*" }
|
|
82
|
+
puts "\n(Your choice: #{branch["options"][response].keys[0]})"
|
|
83
|
+
response = branch["options"][response].values[0].to_i
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
return response
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Get a response for the displayed branch
|
|
90
|
+
#
|
|
91
|
+
# @param branch [Hash] A branch data set
|
|
92
|
+
# @return [Integer] the next branch
|
|
93
|
+
def get_response(branch)
|
|
94
|
+
valid_options = branch["options"].keys.join(", ")
|
|
95
|
+
|
|
96
|
+
print "\n[#{valid_options}]> "
|
|
97
|
+
STDOUT.flush
|
|
98
|
+
response = STDIN.gets.chomp.to_i
|
|
99
|
+
|
|
100
|
+
until branch["options"].keys.include?(response) or response == 0
|
|
101
|
+
print "[## Invalid options. "
|
|
102
|
+
print "Valid options are #{valid_options}, or 0 to exit."
|
|
103
|
+
print "\n[#{valid_options}]> "
|
|
104
|
+
response = STDIN.gets.chomp.to_i
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
return response
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
# Gardner is the module for working with a dialogue tree file
|
|
4
|
+
module Gardner
|
|
5
|
+
|
|
6
|
+
# Parse the tree array into an array of numbered branches, and ordered leaves.
|
|
7
|
+
#
|
|
8
|
+
# @param tree [Array] The dialogue tree
|
|
9
|
+
# @return [Array] An array of numbered branches, with numbered leaves
|
|
10
|
+
def self.prune_branches(tree)
|
|
11
|
+
branches = { 0 => { "desc" => "Thanks for using Sapling!" } }
|
|
12
|
+
tree.each do |b|
|
|
13
|
+
branches[b["branch"]["number"]] = {
|
|
14
|
+
"desc" => b["branch"]["text"],
|
|
15
|
+
"options" => prune_leaves(b["branch"]["leaf"]) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
return branches
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Parse the leaves of a branch into a numbered hash of options.
|
|
22
|
+
#
|
|
23
|
+
# @param leaves [Array] The option of leaf hashes
|
|
24
|
+
# @return [Hash] A numbered hash of options
|
|
25
|
+
def self.prune_leaves(leaves)
|
|
26
|
+
x = 1
|
|
27
|
+
options = {}
|
|
28
|
+
|
|
29
|
+
return options if leaves.nil?
|
|
30
|
+
|
|
31
|
+
leaves.each do |l|
|
|
32
|
+
options[x] = { l["text"] => l["branch"] }
|
|
33
|
+
x += 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return options
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Parse the trunk of the tree.
|
|
40
|
+
#
|
|
41
|
+
# @param tree [Hash] The entire tree
|
|
42
|
+
# @return [Array] The trunk, and the remainder of the tree
|
|
43
|
+
def self.prune_trunk(tree)
|
|
44
|
+
trunk = tree.shift
|
|
45
|
+
|
|
46
|
+
return [trunk,tree]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
require_relative './dialogue'
|
|
2
|
+
require_relative './gardner'
|
|
3
|
+
require_relative './utility'
|
|
4
|
+
|
|
5
|
+
# Planter is the module for creating or editing a tree.
|
|
6
|
+
module Planter
|
|
7
|
+
|
|
8
|
+
# In-memory tree
|
|
9
|
+
class Plot
|
|
10
|
+
|
|
11
|
+
# The tree, trunk, and branches
|
|
12
|
+
attr_accessor :tree, :trunk, :branches
|
|
13
|
+
|
|
14
|
+
# Edit the trunk of the tree
|
|
15
|
+
def edit_trunk
|
|
16
|
+
puts "Current Trunk:\n"
|
|
17
|
+
Dialogue.display_trunk(@trunk, true)
|
|
18
|
+
print "\n[ =EDITING= ](CTRL-C to abort)> "
|
|
19
|
+
STDOUT.flush
|
|
20
|
+
begin
|
|
21
|
+
new_trunk = STDIN.gets.to_s
|
|
22
|
+
rescue Interrupt
|
|
23
|
+
puts "\n**Aborting edit**\n\n"
|
|
24
|
+
new_trunk = @trunk["trunk"]
|
|
25
|
+
end
|
|
26
|
+
@trunk["trunk"] = new_trunk
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Edit a branch on the tree
|
|
30
|
+
#
|
|
31
|
+
# @param branch [Integer] The number of the branch to be edited.
|
|
32
|
+
def edit_branch(branch_no)
|
|
33
|
+
puts "Current Branch:\n"
|
|
34
|
+
Dialogue.display_branch(@branches[branch_no], branch_no, true)
|
|
35
|
+
print "\n[ =EDITING= ](CTRL-C to abort)> "
|
|
36
|
+
STDOUT.flush
|
|
37
|
+
begin
|
|
38
|
+
new_branch = STDIN.gets.to_s
|
|
39
|
+
rescue Interrupt
|
|
40
|
+
puts "\n**Aborting edit**\n\n"
|
|
41
|
+
new_branch = @branches[branch_no]["desc"]
|
|
42
|
+
end
|
|
43
|
+
@branches[branch_no]["desc"] = new_branch
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Edit a leaf on a branch, grasshopper
|
|
47
|
+
#
|
|
48
|
+
# @param branch [Integer] The number of the branch to be edited.
|
|
49
|
+
# @param leaf [Hash] The leaf hash to be edited.
|
|
50
|
+
def edit_leaf(branch, leaf)
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Utilities for editing specific parts of a tree.
|
|
56
|
+
class Spade
|
|
57
|
+
|
|
58
|
+
# The file we parse into a tree
|
|
59
|
+
attr_writer :file
|
|
60
|
+
|
|
61
|
+
def initialize(file)
|
|
62
|
+
@file = file
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Establish and populate a new Plot (in-memory tree), then control the flow
|
|
66
|
+
# of editing the Plot
|
|
67
|
+
def plant
|
|
68
|
+
@plot = Plot.new
|
|
69
|
+
@plot.tree = @file
|
|
70
|
+
@plot.trunk = @file.shift
|
|
71
|
+
@plot.branches = Gardner.prune_branches(@file)
|
|
72
|
+
|
|
73
|
+
next_branch = dig(1)
|
|
74
|
+
until next_branch == 0 do
|
|
75
|
+
next_branch = dig(next_branch)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
puts "\n#{@plot.branches[0]["desc"]}"
|
|
79
|
+
exit
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Function for displaying a single branch in debug mode. We also always
|
|
83
|
+
# display the trunk, since otherwise it's displayed a single time then gone
|
|
84
|
+
# forever (until next time).
|
|
85
|
+
#
|
|
86
|
+
# @param branch_no [Integer] The number of the branch to be displayed.
|
|
87
|
+
def dig(branch_no)
|
|
88
|
+
branch = @plot.branches[branch_no]
|
|
89
|
+
|
|
90
|
+
Dialogue.display_trunk(@plot.trunk, true)
|
|
91
|
+
Dialogue.display_branch(branch, branch_no, true)
|
|
92
|
+
|
|
93
|
+
response = get_response(branch)
|
|
94
|
+
to_branch = parse_response(response, branch_no)
|
|
95
|
+
|
|
96
|
+
return to_branch
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Get a response for the displayed branch
|
|
100
|
+
#
|
|
101
|
+
# @param branch [Hash] A branch data set
|
|
102
|
+
# @return [Integer] the next branch
|
|
103
|
+
def get_response(branch)
|
|
104
|
+
total_branches = @plot.branches.count - 1
|
|
105
|
+
valid_options = ["1-#{total_branches}","t","a","b","x","l","s","q"]
|
|
106
|
+
print_options = valid_options.join(",")
|
|
107
|
+
|
|
108
|
+
print "\n[#{print_options}]> "
|
|
109
|
+
STDOUT.flush
|
|
110
|
+
response = STDIN.gets.chomp.to_s.downcase
|
|
111
|
+
|
|
112
|
+
until valid_options.include?(response) or response.to_i.between?(1,total_branches)
|
|
113
|
+
print "[## Invalid response. "
|
|
114
|
+
print "Valid options are #{print_options}"
|
|
115
|
+
print "\n[#{print_options}]> "
|
|
116
|
+
response = STDIN.gets.chomp.to_s.downcase
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
return response
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Parse the response from get_response
|
|
123
|
+
#
|
|
124
|
+
# @param response [String] The option selected
|
|
125
|
+
# @param branch_no [Integer] The currently-displayed branch
|
|
126
|
+
# @return [Integer] the branch to display
|
|
127
|
+
def parse_response(response, branch_no)
|
|
128
|
+
10.times { print "*" }
|
|
129
|
+
print "\n(Your choice: "
|
|
130
|
+
|
|
131
|
+
if response.to_i >= 1
|
|
132
|
+
print "Change to branch #{response.to_i})\n\n"
|
|
133
|
+
return response.to_i
|
|
134
|
+
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
case response.to_s.downcase
|
|
138
|
+
when "t"
|
|
139
|
+
print "Edit the trunk.)\n\n"
|
|
140
|
+
@plot.edit_trunk
|
|
141
|
+
return branch_no
|
|
142
|
+
when "a"
|
|
143
|
+
print "Add a new branch.)\n\n"
|
|
144
|
+
return branch_no
|
|
145
|
+
when "b"
|
|
146
|
+
print "Edit the current branch.)\n\n"
|
|
147
|
+
@plot.edit_branch(branch_no)
|
|
148
|
+
return branch_no
|
|
149
|
+
when "x"
|
|
150
|
+
print "Delete the current branch.)\n\n"
|
|
151
|
+
return branch_no
|
|
152
|
+
when "l"
|
|
153
|
+
print "Edit leaves of current branch.)\n\n"
|
|
154
|
+
return branch_no
|
|
155
|
+
when "s"
|
|
156
|
+
print "Save changes.)\n\n"
|
|
157
|
+
return branch_no
|
|
158
|
+
when "q"
|
|
159
|
+
print "Quit without saving.)\n\n"
|
|
160
|
+
print "Unsaved changes will be lost. Still quit? [y/n]> "
|
|
161
|
+
verify = STDIN.gets.chomp.to_s.downcase
|
|
162
|
+
|
|
163
|
+
return 0 if verify == "y"
|
|
164
|
+
return branch_no
|
|
165
|
+
else
|
|
166
|
+
print "Unknown option. Returning to current branch.)\n\n"
|
|
167
|
+
return branch_no
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
=begin
|
|
174
|
+
|
|
175
|
+
Process:
|
|
176
|
+
- User selects to create/edit a tree
|
|
177
|
+
- If the user presented a file, use it as the tree file
|
|
178
|
+
- If the user failed to provide a file, create a new tree file in the current directory
|
|
179
|
+
|
|
180
|
+
- Check if the file is empty.
|
|
181
|
+
- If so, assume a new tree
|
|
182
|
+
- If not, verify formatting
|
|
183
|
+
|
|
184
|
+
- If new tree, prompt for trunk
|
|
185
|
+
- If existing tree, display trunk and first branch
|
|
186
|
+
|
|
187
|
+
- At this point, editing is the same
|
|
188
|
+
- Prompt provides options:
|
|
189
|
+
- #: Go to that branch number
|
|
190
|
+
- T: Modify the tree trunk
|
|
191
|
+
- A: Add a new branch (append to list of branches)
|
|
192
|
+
- B: Modify the current branch description
|
|
193
|
+
- X: Delete the current branch (does this renumber branches?)
|
|
194
|
+
- L: Modify the current leaves, respond with leaf prompt
|
|
195
|
+
- S: Save changes
|
|
196
|
+
- Q: Quit
|
|
197
|
+
|
|
198
|
+
- Example prompt:
|
|
199
|
+
[ 0-5,T,A,B,X,L,S,Q ]>
|
|
200
|
+
- Leaf prompt:
|
|
201
|
+
|
|
202
|
+
Details:
|
|
203
|
+
|
|
204
|
+
- Regardless of the file existing, the user will be editing a Hash, not the actual YAML file
|
|
205
|
+
- Use Gardner to build and interact with the tree
|
|
206
|
+
- Use Planter to modify the tree "in memory" (aka, the hash)
|
|
207
|
+
- Use Dialog to interact with the tree "in memory", to test-run it
|
|
208
|
+
- After each edit option, display the current branch with the new changes.
|
|
209
|
+
|
|
210
|
+
=end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Utility functionality for all of Sapling to reference
|
|
2
|
+
|
|
3
|
+
# Constants
|
|
4
|
+
|
|
5
|
+
# A series of constants for handing a brand new tree. The skeleton tree provides
|
|
6
|
+
# a very basic introduction to Sapling. More details can be found in the
|
|
7
|
+
# documentation.
|
|
8
|
+
|
|
9
|
+
# The default trunk text of a new tree
|
|
10
|
+
SKELE_TRUNK_TEXT = "Welcome to the Sapling Editor. For details, please see the
|
|
11
|
+
documentation!"
|
|
12
|
+
|
|
13
|
+
# The default first-branch text of a new tree
|
|
14
|
+
SKELE_BRANCH_TEXT = "The first branch is always shown by default. It should act
|
|
15
|
+
as the introduction to the story. From here, the user enters your world!"
|
|
16
|
+
|
|
17
|
+
# The default first-leaf text of the first branch of a new tree. The leaf points
|
|
18
|
+
# to it's own branch. The only way out of the program is to either force-quit or
|
|
19
|
+
# reply with option 0.
|
|
20
|
+
SKELE_LEAF_TEXT = "Each branch can have any number of leaves, which represent
|
|
21
|
+
the options a user has on that branch. Each leaf points to another branch, or
|
|
22
|
+
can point to branch 0 to immediately exit."
|
|
23
|
+
|
|
24
|
+
# The final tree
|
|
25
|
+
SKELETON_TREE = [
|
|
26
|
+
{"trunk" => "#{SKELE_TRUNK_TEXT}"},
|
|
27
|
+
{"branch" => {
|
|
28
|
+
"number" => 1,
|
|
29
|
+
"text" => "#{SKELE_BRANCH_TEXT}",
|
|
30
|
+
"leaf" => [{
|
|
31
|
+
"text" => "#{SKELE_LEAF_TEXT}",
|
|
32
|
+
"branch" => 1
|
|
33
|
+
}]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Verify that a file is a dialogue tree file.
|
|
40
|
+
#
|
|
41
|
+
# @param file [File] The provided file
|
|
42
|
+
# @return [Boolean] True if the file is a tree; false otherwise
|
|
43
|
+
def verify_tree(file)
|
|
44
|
+
results = []
|
|
45
|
+
begin
|
|
46
|
+
tree = YAML.load_file(file)
|
|
47
|
+
results << tree[0].keys.include?("trunk")
|
|
48
|
+
results << tree[1]["branch"].keys.include?("number")
|
|
49
|
+
results << tree[1]["branch"].keys.include?("text")
|
|
50
|
+
results << tree[1]["branch"].keys.include?("leaf")
|
|
51
|
+
rescue
|
|
52
|
+
puts "Sorry chummer, I don't think this is a tree."
|
|
53
|
+
puts "Verify your YAML file is formatted properly."
|
|
54
|
+
results << false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
results.include?(false) ? false : true
|
|
58
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sapling-dialogue
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Bill Niblock
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-10-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Create, edit, and traverse Dialogue trees
|
|
14
|
+
email: azulien@gmail.com
|
|
15
|
+
executables:
|
|
16
|
+
- sapling
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- bin/sapling
|
|
21
|
+
- lib/sapling.rb
|
|
22
|
+
- lib/sapling/dialogue.rb
|
|
23
|
+
- lib/sapling/gardner.rb
|
|
24
|
+
- lib/sapling/planter.rb
|
|
25
|
+
- lib/sapling/utility.rb
|
|
26
|
+
homepage: http://www.theinternetvagabond.com/sapling/
|
|
27
|
+
licenses:
|
|
28
|
+
- MIT
|
|
29
|
+
metadata: {}
|
|
30
|
+
post_install_message:
|
|
31
|
+
rdoc_options: []
|
|
32
|
+
require_paths:
|
|
33
|
+
- lib
|
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
requirements: []
|
|
45
|
+
rubyforge_project:
|
|
46
|
+
rubygems_version: 2.6.13
|
|
47
|
+
signing_key:
|
|
48
|
+
specification_version: 4
|
|
49
|
+
summary: A Dialogue Tree Utility
|
|
50
|
+
test_files: []
|