gamefic 0.2.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gamefic/action.rb +87 -56
- data/lib/gamefic/ansi.rb +55 -0
- data/lib/gamefic/character.rb +130 -76
- data/lib/gamefic/command.rb +19 -0
- data/lib/gamefic/core_ext/array.rb +51 -40
- data/lib/gamefic/core_ext/string.rb +4 -0
- data/lib/gamefic/describable.rb +108 -46
- data/lib/gamefic/direction.rb +46 -0
- data/lib/gamefic/director/delegate.rb +91 -0
- data/lib/gamefic/director/order.rb +10 -0
- data/lib/gamefic/director/parser.rb +119 -0
- data/lib/gamefic/director.rb +16 -197
- data/lib/gamefic/engine/cgi.rb +221 -0
- data/lib/gamefic/engine/tty.rb +237 -0
- data/lib/gamefic/engine.rb +88 -67
- data/lib/gamefic/entity.rb +96 -69
- data/lib/gamefic/grammar/conjugator.rb +20 -0
- data/lib/gamefic/grammar/gender.rb +11 -0
- data/lib/gamefic/grammar/person.rb +10 -0
- data/lib/gamefic/grammar/plural.rb +13 -0
- data/lib/gamefic/grammar/pronouns.rb +60 -0
- data/lib/gamefic/grammar/tense.rb +6 -0
- data/lib/gamefic/grammar/verb_set.rb +43 -0
- data/lib/gamefic/grammar/verbs.rb +25 -0
- data/lib/gamefic/grammar/word_adapter.rb +36 -0
- data/lib/gamefic/grammar.rb +13 -0
- data/lib/gamefic/html.rb +53 -0
- data/lib/gamefic/keywords.rb +51 -33
- data/lib/gamefic/node.rb +65 -58
- data/lib/gamefic/plot/article_mount.rb +22 -0
- data/lib/gamefic/plot/command_mount.rb +88 -0
- data/lib/gamefic/plot/entity_mount.rb +45 -0
- data/lib/gamefic/plot/query_mount.rb +9 -0
- data/lib/gamefic/plot/scene_mount.rb +181 -0
- data/lib/gamefic/plot/you_mount.rb +22 -0
- data/lib/gamefic/plot.rb +296 -247
- data/lib/gamefic/query/ambiguous_children.rb +5 -0
- data/lib/gamefic/query/base.rb +265 -0
- data/lib/gamefic/query/children.rb +10 -0
- data/lib/gamefic/query/expression.rb +47 -0
- data/lib/gamefic/query/family.rb +10 -0
- data/lib/gamefic/query/many_children.rb +7 -0
- data/lib/gamefic/query/matches.rb +11 -0
- data/lib/gamefic/query/parent.rb +10 -0
- data/lib/gamefic/query/plural_children.rb +14 -0
- data/lib/gamefic/query/self.rb +10 -0
- data/lib/gamefic/query/siblings.rb +10 -0
- data/lib/gamefic/query/text.rb +43 -0
- data/lib/gamefic/query.rb +19 -203
- data/lib/gamefic/rule.rb +18 -0
- data/lib/gamefic/scene/active.rb +25 -0
- data/lib/gamefic/scene/concluded.rb +22 -0
- data/lib/gamefic/scene/multiplechoice.rb +74 -0
- data/lib/gamefic/scene/paused.rb +26 -0
- data/lib/gamefic/scene/yesorno.rb +43 -0
- data/lib/gamefic/scene.rb +125 -0
- data/lib/gamefic/script/base.rb +33 -0
- data/lib/gamefic/script/file.rb +14 -0
- data/lib/gamefic/script/text.rb +14 -0
- data/lib/gamefic/script.rb +9 -0
- data/lib/gamefic/serialized.rb +24 -0
- data/lib/gamefic/shell.rb +9 -247
- data/lib/gamefic/snapshots.rb +134 -0
- data/lib/gamefic/source/base.rb +12 -0
- data/lib/gamefic/source/file.rb +23 -0
- data/lib/gamefic/source/text.rb +16 -0
- data/lib/gamefic/source.rb +9 -0
- data/lib/gamefic/stage.rb +75 -0
- data/lib/gamefic/syntax.rb +106 -124
- data/lib/gamefic/tester.rb +20 -0
- data/lib/gamefic/version.rb +3 -0
- data/lib/gamefic.rb +18 -12
- metadata +102 -70
- data/lib/gamefic/base.rb +0 -10
- data/lib/gamefic/before.rb +0 -12
- data/lib/gamefic/import/basics/actions/close.rb +0 -16
- data/lib/gamefic/import/basics/actions/commands.rb +0 -3
- data/lib/gamefic/import/basics/actions/drop-in.rb +0 -17
- data/lib/gamefic/import/basics/actions/drop-on.rb +0 -16
- data/lib/gamefic/import/basics/actions/drop.rb +0 -30
- data/lib/gamefic/import/basics/actions/enter.rb +0 -16
- data/lib/gamefic/import/basics/actions/go.rb +0 -35
- data/lib/gamefic/import/basics/actions/inventory.rb +0 -8
- data/lib/gamefic/import/basics/actions/leave.rb +0 -29
- data/lib/gamefic/import/basics/actions/look-in-at.rb +0 -27
- data/lib/gamefic/import/basics/actions/look-under.rb +0 -3
- data/lib/gamefic/import/basics/actions/look.rb +0 -71
- data/lib/gamefic/import/basics/actions/nil.rb +0 -25
- data/lib/gamefic/import/basics/actions/open.rb +0 -23
- data/lib/gamefic/import/basics/actions/quit.rb +0 -3
- data/lib/gamefic/import/basics/actions/take.rb +0 -107
- data/lib/gamefic/import/basics/entities/container.rb +0 -8
- data/lib/gamefic/import/basics/entities/entity.rb +0 -11
- data/lib/gamefic/import/basics/entities/fixture.rb +0 -5
- data/lib/gamefic/import/basics/entities/item.rb +0 -5
- data/lib/gamefic/import/basics/entities/portal.rb +0 -40
- data/lib/gamefic/import/basics/entities/room.rb +0 -30
- data/lib/gamefic/import/basics/entities/scenery.rb +0 -5
- data/lib/gamefic/import/basics/entities/supporter.rb +0 -6
- data/lib/gamefic/import/basics/entities/thing.rb +0 -16
- data/lib/gamefic/import/basics/queries/reachable.rb +0 -38
- data/lib/gamefic/import/basics/queries/room.rb +0 -8
- data/lib/gamefic/import/basics/queries/visible.rb +0 -32
- data/lib/gamefic/import/basics/rules/has-enough-light.rb +0 -14
- data/lib/gamefic/import/basics.old/actions/container.rb +0 -112
- data/lib/gamefic/import/basics.old/actions/inventory.rb +0 -50
- data/lib/gamefic/import/basics.old/actions/look.rb +0 -53
- data/lib/gamefic/import/basics.old/actions/meta.rb +0 -6
- data/lib/gamefic/import/basics.old/actions/traversal.rb +0 -35
- data/lib/gamefic/import/basics.old/actions.rb +0 -1
- data/lib/gamefic/import/basics.old/entities/container.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/fixture.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/item.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/portal.rb +0 -43
- data/lib/gamefic/import/basics.old/entities/room.rb +0 -27
- data/lib/gamefic/import/basics.old/entities/scenery.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/supporter.rb +0 -3
- data/lib/gamefic/import/basics.old/entities.rb +0 -1
- data/lib/gamefic/import/basics.old/room_modes.rb +0 -48
- data/lib/gamefic/import/basics.rb +0 -6
- data/lib/gamefic/import/room_modes.rb +0 -48
- data/lib/gamefic/import/standard.rb +0 -1
- data/lib/gamefic/meta.rb +0 -12
- data/lib/gamefic/optionset.rb +0 -114
- data/lib/gamefic/requirement.rb +0 -14
- data/lib/gamefic/story.rb +0 -14
- data/lib/gamefic/thing.rb +0 -7
data/lib/gamefic/entity.rb
CHANGED
@@ -1,76 +1,103 @@
|
|
1
|
-
require "digest/md5"
|
2
1
|
require "gamefic/node"
|
3
2
|
require "gamefic/describable"
|
4
|
-
require "gamefic/
|
3
|
+
require "gamefic/serialized"
|
5
4
|
|
6
5
|
module Gamefic
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
include
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
7
|
+
class Entity
|
8
|
+
include Node
|
9
|
+
include Describable
|
10
|
+
include Serialized
|
11
|
+
extend Serialized::ClassMethods
|
12
|
+
include Grammar::WordAdapter
|
13
|
+
|
14
|
+
attr_reader :session, :plot
|
15
|
+
serialize :name, :parent, :description
|
16
|
+
|
17
|
+
def initialize(plot, args = {})
|
18
|
+
if (plot.kind_of?(Plot) == false)
|
19
|
+
raise "First argument must be a Plot"
|
20
|
+
end
|
21
|
+
pre_initialize
|
22
|
+
@plot = plot
|
23
|
+
@plot.send :add_entity, self
|
24
|
+
args.each { |key, value|
|
25
|
+
send "#{key}=", value
|
26
|
+
}
|
27
|
+
@update_procs = Array.new
|
28
|
+
@session = Hash.new
|
29
|
+
yield self if block_given?
|
30
|
+
post_initialize
|
31
|
+
end
|
32
|
+
def uid
|
33
|
+
if @uid == nil
|
34
|
+
@uid = self.object_id.to_s
|
35
|
+
end
|
36
|
+
@uid
|
37
|
+
end
|
38
|
+
def pre_initialize
|
39
|
+
# raise NotImplementedError, "#{self.class} must implement post_initialize"
|
40
|
+
end
|
41
|
+
def post_initialize
|
42
|
+
# raise NotImplementedError, "#{self.class} must implement post_initialize"
|
43
|
+
end
|
44
|
+
def tell(message)
|
45
|
+
#TODO: Should this even be here? In all likelihood, only Characters receive tells, right?
|
46
|
+
#TODO: On second thought, it might be interesting to see logs from an npc point of view.
|
47
|
+
end
|
48
|
+
def stream(message)
|
49
|
+
# Unlike tell, this method sends raw data without formatting.
|
50
|
+
end
|
51
|
+
|
52
|
+
# Execute the entity's on_update blocks.
|
53
|
+
# This method is typically called by the Engine that manages game execution.
|
54
|
+
#
|
55
|
+
def update
|
56
|
+
@update_procs.each { |p|
|
57
|
+
p.call self
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
# Add a block to be executed when the game updates a turn.
|
62
|
+
#
|
63
|
+
# @yieldparam [Entity]
|
64
|
+
def on_update(&block)
|
65
|
+
@update_procs.push block
|
66
|
+
end
|
67
|
+
|
68
|
+
# Set the Entity's parent.
|
69
|
+
#
|
70
|
+
# @param node [Entity] The new parent.
|
71
|
+
def parent=(node)
|
72
|
+
if node != nil and node.kind_of?(Entity) == false
|
73
|
+
raise "Entity's parent must be an Entity"
|
74
|
+
end
|
75
|
+
super
|
76
|
+
end
|
77
|
+
|
78
|
+
# Remove this Entity from its current Plot.
|
79
|
+
#
|
80
|
+
def destroy
|
81
|
+
self.parent = nil
|
82
|
+
# TODO: Need to call this private method here?
|
83
|
+
@plot.send(:rem_entity, self)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Get an extended property.
|
87
|
+
#
|
88
|
+
# @param key [Symbol] The property's name.
|
89
|
+
def [](key)
|
90
|
+
session[key]
|
91
|
+
end
|
92
|
+
|
93
|
+
# Set an extended property.
|
94
|
+
#
|
95
|
+
# @param key [Symbol] The property's name.
|
96
|
+
# @param value The value to set.
|
97
|
+
def []=(key, value)
|
98
|
+
session[key] = value
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
75
102
|
|
76
103
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'gamefic'
|
2
|
+
require 'gamefic/grammar'
|
3
|
+
|
4
|
+
module Gamefic::Grammar
|
5
|
+
module Conjugator
|
6
|
+
module ClassMethods
|
7
|
+
@@conjugated_verbs = {}
|
8
|
+
def conjugate infinitive, tense, *forms
|
9
|
+
@@conjugated_verbs[infinitive] ||= {}
|
10
|
+
@@conjugated_verbs[infinitive][tense] = VerbSet.new(infinitive, *forms)
|
11
|
+
end
|
12
|
+
def conjugated_verbs
|
13
|
+
@@conjugated_verbs
|
14
|
+
end
|
15
|
+
end
|
16
|
+
#def self.included(base)
|
17
|
+
# base.extend ClassMethods
|
18
|
+
#end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'gamefic'
|
2
|
+
require 'gamefic/grammar'
|
3
|
+
|
4
|
+
module Gamefic::Grammar
|
5
|
+
class Pronouns
|
6
|
+
def initialize object
|
7
|
+
@object = object
|
8
|
+
end
|
9
|
+
def subj
|
10
|
+
Pronouns.get_pronoun_set(@object)[0]
|
11
|
+
end
|
12
|
+
def obj
|
13
|
+
Pronouns.get_pronoun_set(@object)[1]
|
14
|
+
end
|
15
|
+
def poss
|
16
|
+
Pronouns.get_pronoun_set(@object)[2]
|
17
|
+
end
|
18
|
+
def Subj
|
19
|
+
subj.cap_first
|
20
|
+
end
|
21
|
+
def Obj
|
22
|
+
obj.cap_first
|
23
|
+
end
|
24
|
+
def Poss
|
25
|
+
obj.cap_first
|
26
|
+
end
|
27
|
+
def self.get_pronoun_set(obj)
|
28
|
+
set = Pronouns.sets["#{obj.person}"]
|
29
|
+
if set.nil?
|
30
|
+
set = Pronouns.sets["#{obj.person}:#{obj.plural? ? 'plural' : 'singular'}"]
|
31
|
+
end
|
32
|
+
if set.nil?
|
33
|
+
set = Pronouns.sets["#{obj.person}:#{obj.plural? ? 'plural' : 'singular'}:#{obj.gender}"]
|
34
|
+
end
|
35
|
+
if set.nil?
|
36
|
+
raise "Pronoun set could not be determined"
|
37
|
+
end
|
38
|
+
set
|
39
|
+
end
|
40
|
+
# TODO Consider implementing method_missing to determine correct pronoun
|
41
|
+
# from example, e.g., "he" would change to "she" for female entities
|
42
|
+
def self.sets
|
43
|
+
if @sets.nil?
|
44
|
+
@sets = {}
|
45
|
+
@sets["1:singular"] = ["I", "me", "my"]
|
46
|
+
@sets["2"] = ["you", "you", "your"]
|
47
|
+
@sets["3:singular:male"] = ["he", "him", "his"]
|
48
|
+
@sets["3:singular:female"] = ["she", "her", "her"]
|
49
|
+
# "other" refers to a person or living being that is neither
|
50
|
+
# male or female or for whom gender is unspecified. It's
|
51
|
+
# typically used to avoid referring to a person as "it."
|
52
|
+
@sets["3:singular:other"] = ["they", "them", "their"]
|
53
|
+
@sets["3:singular:neutral"] = ["it", "it", "its"]
|
54
|
+
@sets["1:plural"] = ["we", "us", "our"]
|
55
|
+
@sets["3:plural"] = ["they", "them", "their"]
|
56
|
+
end
|
57
|
+
@sets
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'gamefic/grammar'
|
2
|
+
|
3
|
+
module Gamefic::Grammar
|
4
|
+
class VerbSet
|
5
|
+
def initialize infinitive, *forms
|
6
|
+
# TODO what to do with the tense?
|
7
|
+
@infinitive = infinitive.to_s
|
8
|
+
@forms = {}
|
9
|
+
form = forms[0]
|
10
|
+
@forms["1:singular"] = form.nil? ? @infinitive.to_s : form.to_s
|
11
|
+
form = forms[1]
|
12
|
+
@forms["2:singular"] = form.nil? ? @infinitive.to_s : form.to_s
|
13
|
+
form = forms[2]
|
14
|
+
@forms["3:singular"] = form.nil? ? generate_third_singular : form.to_s
|
15
|
+
form = forms[3]
|
16
|
+
@forms["1:plural"] = form.nil? ? @infinitive.to_s : form.to_s
|
17
|
+
form = forms[4]
|
18
|
+
@forms["2:plural"] = form.nil? ? @forms["1:plural"] : form.to_s
|
19
|
+
form = forms[5]
|
20
|
+
@forms["3:plural"] = form.nil? ? @forms["1:plural"] : form.to_s
|
21
|
+
end
|
22
|
+
def conjugate pronoun
|
23
|
+
form = @forms["#{pronoun.person}"]
|
24
|
+
if form.nil?
|
25
|
+
form = @forms["#{pronoun.person}:#{pronoun.plural? ? 'plural' : 'singular'}"]
|
26
|
+
end
|
27
|
+
if form.nil?
|
28
|
+
raise "Unable to conjugate #{@infinitive}"
|
29
|
+
end
|
30
|
+
form
|
31
|
+
end
|
32
|
+
private
|
33
|
+
def generate_third_singular
|
34
|
+
if @infinitive.end_with?('o')
|
35
|
+
@infinitive + "es"
|
36
|
+
elsif @infinitive.end_with?('ry')
|
37
|
+
@infinitive[0..-2] + "ies"
|
38
|
+
else
|
39
|
+
@infinitive + "s"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'gamefic'
|
2
|
+
require 'gamefic/grammar'
|
3
|
+
|
4
|
+
module Gamefic::Grammar
|
5
|
+
class Verbs
|
6
|
+
extend Gamefic::Grammar::Conjugator::ClassMethods
|
7
|
+
def initialize obj
|
8
|
+
@pronoun = obj
|
9
|
+
self.class.conjugated_verbs.each_pair { |infinitive, verbset|
|
10
|
+
define_singleton_method infinitive do
|
11
|
+
verbset[:present].conjugate @pronoun
|
12
|
+
end
|
13
|
+
}
|
14
|
+
end
|
15
|
+
def method_missing infinitive, *args, &block
|
16
|
+
Gamefic::Grammar::VerbSet.new(infinitive, nil, *args).conjugate(@pronoun)
|
17
|
+
end
|
18
|
+
def [] infinitive
|
19
|
+
words = infinitive.split_words
|
20
|
+
Gamefic::Grammar::VerbSet.new(words[0], nil).conjugate(@pronoun) + (words.length > 1 ? ' ' + words[1..-1].join(' ') : '')
|
21
|
+
end
|
22
|
+
conjugate :be, :present, :am, :are, :is, :are
|
23
|
+
conjugate :have, :present, :have, :have, :has, :have
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'gamefic/grammar'
|
2
|
+
require 'gamefic/grammar/gender'
|
3
|
+
|
4
|
+
module Gamefic::Grammar
|
5
|
+
module WordAdapter
|
6
|
+
include Gender
|
7
|
+
include Person
|
8
|
+
include Plural
|
9
|
+
# @return [Gamefic::Grammar::Pronouns]
|
10
|
+
def pronoun
|
11
|
+
@pronoun ||= Grammar::Pronouns.new(self)
|
12
|
+
end
|
13
|
+
# @return [Gamefic::Grammar::Verbs]
|
14
|
+
def verb
|
15
|
+
@verb ||= Grammar::Verbs.new(self)
|
16
|
+
end
|
17
|
+
def contract words
|
18
|
+
@contractions ||= {
|
19
|
+
"I am" => "I'm",
|
20
|
+
"you are" => "you're",
|
21
|
+
"he is" => "he's",
|
22
|
+
"she is" => "she's",
|
23
|
+
"it is" => "it's",
|
24
|
+
"we are" => "we're",
|
25
|
+
"they are" => "they're",
|
26
|
+
"am not" => "am not",
|
27
|
+
"are not" => "aren't",
|
28
|
+
"is not" => "isn't",
|
29
|
+
"do not" => "don't",
|
30
|
+
"does not" => "doesn't"
|
31
|
+
}
|
32
|
+
src = pronoun.subj + " " + verb.send(words)
|
33
|
+
@contractions[src] || src
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Gamefic
|
2
|
+
module Grammar
|
3
|
+
autoload :Tense, 'gamefic/grammar/tense'
|
4
|
+
autoload :Pronouns, 'gamefic/grammar/pronouns'
|
5
|
+
autoload :Conjugator, 'gamefic/grammar/conjugator'
|
6
|
+
autoload :Verbs, 'gamefic/grammar/verbs'
|
7
|
+
autoload :VerbSet, 'gamefic/grammar/verb_set'
|
8
|
+
autoload :Person, 'gamefic/grammar/person'
|
9
|
+
autoload :Plural, 'gamefic/grammar/plural'
|
10
|
+
autoload :Gender, 'gamefic/grammar/gender'
|
11
|
+
autoload :WordAdapter, 'gamefic/grammar/word_adapter'
|
12
|
+
end
|
13
|
+
end
|
data/lib/gamefic/html.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module Gamefic
|
4
|
+
|
5
|
+
module Html
|
6
|
+
def self.fix_ampersands(text)
|
7
|
+
codes = []
|
8
|
+
ENTITIES.keys.each { |e|
|
9
|
+
codes.push e[1..-1]
|
10
|
+
}
|
11
|
+
piped = codes.join('|')
|
12
|
+
re = Regexp.new("&(?!(#{piped}))")
|
13
|
+
text.gsub(re, '&\1')
|
14
|
+
end
|
15
|
+
def self.encode(text)
|
16
|
+
Gamefic::Html::ENTITIES.each { |k, v|
|
17
|
+
while text.include?(k)
|
18
|
+
text[v] = k
|
19
|
+
end
|
20
|
+
}
|
21
|
+
text
|
22
|
+
end
|
23
|
+
def self.decode(text)
|
24
|
+
Gamefic::Html::ENTITIES.each { |k, v|
|
25
|
+
while text.include?(k)
|
26
|
+
text[k] = v
|
27
|
+
end
|
28
|
+
}
|
29
|
+
text
|
30
|
+
end
|
31
|
+
def self.parse(code)
|
32
|
+
code = fix_ampersands(code).strip
|
33
|
+
last = nil
|
34
|
+
begin
|
35
|
+
doc = REXML::Document.new code
|
36
|
+
rescue REXML::ParseException => e
|
37
|
+
if e.source.buffer != last
|
38
|
+
if e.source.buffer[0,1] == '<'
|
39
|
+
code = code[0,(code.length - e.source.buffer.length)] + '<' + e.source.buffer[1..-1]
|
40
|
+
last = e.source.buffer
|
41
|
+
retry
|
42
|
+
end
|
43
|
+
end
|
44
|
+
raise e
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module Html
|
50
|
+
ENTITIES = { """ => "\"", "&" => "&", "<" => "<", ">" => ">", " " => " ", "¡" => "¡", "¢" => "¢", "£" => "£", "¤" => "¤", "¥" => "¥", "¦" => "¦", "§" => "§", "¨" => "¨", "©" => "©", "ª" => "ª", "«" => "«", "¬" => "¬", "­" => "", "®" => "®", "¯" => "¯", "°" => "°", "±" => "±", "²" => "²", "³" => "³", "´" => "´", "µ" => "µ", "¶" => "¶", "·" => "·", "¸" => "¸", "¹" => "¹", "º" => "º", "»" => "»", "¼" => "¼", "½" => "½", "¾" => "¾", "¿" => "¿", "À" => "À", "Á" => "Á", "Â" => "Â", "Ã" => "Ã", "Ä" => "Ä", "Å" => "Å", "Æ" => "Æ", "Ç" => "Ç", "È" => "È", "É" => "É", "Ê" => "Ê", "Ë" => "Ë", "Ì" => "Ì", "Í" => "Í", "Î" => "Î", "Ï" => "Ï", "Ð" => "Ð", "Ñ" => "Ñ", "Ò" => "Ò", "Ó" => "Ó", "Ô" => "Ô", "Õ" => "Õ", "Ö" => "Ö", "×" => "×", "Ø" => "Ø", "Ù" => "Ù", "Ú" => "Ú", "Û" => "Û", "Ü" => "Ü", "Ý" => "Ý", "Þ" => "Þ", "ß" => "ß", "à" => "à", "á" => "á", "â" => "â", "ã" => "ã", "ä" => "ä", "å" => "å", "æ" => "æ", "ç" => "ç", "è" => "è", "é" => "é", "ê" => "ê", "ë" => "ë", "ì" => "ì", "í" => "í", "î" => "î", "ï" => "ï", "ð" => "ð", "ñ" => "ñ", "ò" => "ò", "ó" => "ó", "ô" => "ô", "õ" => "õ", "ö" => "ö", "÷" => "÷", "ø" => "ø", "ù" => "ù", "ú" => "ú", "û" => "û", "ü" => "ü", "ý" => "ý", "þ" => "þ", "ÿ" => "ÿ", "Œ" => "Œ", "œ" => "œ", "Š" => "Š", "š" => "š", "Ÿ" => "Ÿ", "ƒ" => "ƒ", "ˆ" => "ˆ", "˜" => "˜", "Α" => "Α", "Β" => "Β", "Γ" => "Γ", "Δ" => "Δ", "Ε" => "Ε", "Ζ" => "Ζ", "Η" => "Η", "Θ" => "Θ", "Ι" => "Ι", "Κ" => "Κ", "Λ" => "Λ", "Μ" => "Μ", "Ν" => "Ν", "Ξ" => "Ξ", "Ο" => "Ο", "Π" => "Π", "Ρ" => "Ρ", "Σ" => "Σ", "Τ" => "Τ", "Υ" => "Υ", "Φ" => "Φ", "Χ" => "Χ", "Ψ" => "Ψ", "Ω" => "Ω", "α" => "α", "β" => "β", "γ" => "γ", "δ" => "δ", "ε" => "ε", "ζ" => "ζ", "η" => "η", "θ" => "θ", "ι" => "ι", "κ" => "κ", "λ" => "λ", "μ" => "μ", "ν" => "ν", "ξ" => "ξ", "ο" => "ο", "π" => "π", "ρ" => "ρ", "ς" => "ς", "σ" => "σ", "τ" => "τ", "υ" => "υ", "φ" => "φ", "χ" => "χ", "ψ" => "ψ", "ω" => "ω", "ϑ" => "ϑ", "ϒ" => "ϒ", "ϖ" => "ϖ", " " => " ", " " => " ", " " => " ", "‌" => "", "‍" => "", "‎" => "", "‏" => "", "–" => "–", "—" => "—", "‘" => "‘", "’" => "’", "‚" => "‚", "“" => "“", "”" => "”", "„" => "„", "†" => "†", "‡" => "‡", "•" => "•", "…" => "…", "‰" => "‰", "′" => "′", "″" => "″", "‹" => "‹", "›" => "›", "‾" => "‾", "⁄" => "⁄", "€" => "€", "ℑ" => "ℑ", "℘" => "℘", "ℜ" => "ℜ", "™" => "™", "ℵ" => "ℵ", "←" => "←", "↑" => "↑", "→" => "→", "↓" => "↓", "↔" => "↔", "↵" => "↵", "⇐" => "⇐", "⇑" => "⇑", "⇒" => "⇒", "⇓" => "⇓", "⇔" => "⇔", "∀" => "∀", "∂" => "∂", "∃" => "∃", "∅" => "∅", "∇" => "∇", "∈" => "∈", "∉" => "∉", "∋" => "∋", "∏" => "∏", "∑" => "∑", "−" => "−", "∗" => "∗", "√" => "√", "∝" => "∝", "∞" => "∞", "∠" => "∠", "∧" => "∧", "∨" => "∨", "∩" => "∩", "∪" => "∪", "∫" => "∫", "∴" => "∴", "∼" => "∼", "≅" => "≅", "≈" => "≈", "≠" => "≠", "≡" => "≡", "≤" => "≤", "≥" => "≥", "⊂" => "⊂", "⊃" => "⊃", "⊄" => "⊄", "⊆" => "⊆", "⊇" => "⊇", "⊕" => "⊕", "⊗" => "⊗", "⊥" => "⊥", "⋅" => "⋅", "⌈" => "⌈", "⌉" => "⌉", "⌊" => "⌊", "⌋" => "⌋", "⟨" => "〈", "⟩" => "〉", "◊" => "◊", "♠" => "♠", "♣" => "♣", "♥" => "♥", "♦" => "♦" }
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/gamefic/keywords.rb
CHANGED
@@ -2,41 +2,59 @@
|
|
2
2
|
|
3
3
|
module Gamefic
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
class Keywords < Array
|
6
|
+
def initialize(statement = '')
|
7
|
+
if statement.kind_of?(Keywords)
|
8
|
+
self.concat statement
|
9
|
+
else
|
10
10
|
if statement.kind_of?(Array)
|
11
11
|
statement = statement.join(' ')
|
12
12
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
13
|
+
self.concat statement.to_s.gsub(/[^a-z0-9]/i, ' ').strip.downcase.split(' ')
|
14
|
+
end
|
15
|
+
# TODO: This routine is stubbed to allow any combination of letters and
|
16
|
+
# numbers as a keyword. Since we're doing this, there's a distinct
|
17
|
+
# possibility that the Keywords class can be deprecated.
|
18
|
+
#self.delete_if { |w|
|
19
|
+
# w.length < 2 or w == 'an' or w == 'the'
|
20
|
+
#}
|
21
|
+
#self.uniq!
|
22
|
+
self
|
23
|
+
end
|
24
|
+
def found_in(other, fuzzy = false)
|
25
|
+
matches = 0.0
|
26
|
+
self.each { |my_word|
|
27
|
+
if other.include?(my_word)
|
28
|
+
matches = matches + 1.0
|
29
|
+
else
|
30
|
+
other.each { |other_word|
|
31
|
+
if my_word.length < other_word.length
|
32
|
+
if other_word[0, my_word.length] == my_word and my_word.length > 2
|
33
|
+
matches = matches + (my_word.length.to_f / other_word.length.to_f)
|
34
|
+
end
|
35
|
+
elsif fuzzy
|
36
|
+
fuzzy_word = my_word
|
37
|
+
if fuzzy_word.end_with?('ies')
|
38
|
+
fuzzy_word = fuzzy_word[0..-4]
|
39
|
+
elsif fuzzy_word.end_with?('ae')
|
40
|
+
fuzzy_word = fuzzy_word[0..-3]
|
41
|
+
elsif fuzzy_word.end_with?('s') or fuzzy_word.end_with?('i')
|
42
|
+
fuzzy_word = fuzzy_word[0..-2]
|
43
|
+
end
|
44
|
+
if other_word[0, fuzzy_word.length] == fuzzy_word and fuzzy_word.length > 2
|
45
|
+
matches = matches + (fuzzy_word.length.to_f / other_word.length.to_f)
|
46
|
+
elsif fuzzy_word[0, other_word.length] == other_word and other_word.length > 2
|
47
|
+
matches = matches + (fuzzy_word.length.to_f / other_word.length.to_f)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
}
|
51
|
+
end
|
52
|
+
}
|
53
|
+
return matches
|
54
|
+
end
|
55
|
+
def to_s
|
56
|
+
self.join(' ')
|
57
|
+
end
|
58
|
+
end
|
41
59
|
|
42
60
|
end
|