gherkin 2.2.5-x86-mingw32

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.
Files changed (132) hide show
  1. data/.gitattributes +2 -0
  2. data/.gitignore +11 -0
  3. data/.mailmap +2 -0
  4. data/.rspec +1 -0
  5. data/.rvmrc +1 -0
  6. data/Gemfile +5 -0
  7. data/History.txt +306 -0
  8. data/LICENSE +20 -0
  9. data/README.rdoc +59 -0
  10. data/Rakefile +16 -0
  11. data/VERSION +1 -0
  12. data/bin/gherkin +5 -0
  13. data/build_native_gems.sh +8 -0
  14. data/cucumber.yml +3 -0
  15. data/features/escaped_pipes.feature +8 -0
  16. data/features/feature_parser.feature +237 -0
  17. data/features/json_formatter.feature +278 -0
  18. data/features/json_parser.feature +318 -0
  19. data/features/native_lexer.feature +19 -0
  20. data/features/parser_with_native_lexer.feature +205 -0
  21. data/features/pretty_formatter.feature +15 -0
  22. data/features/step_definitions/eyeball_steps.rb +3 -0
  23. data/features/step_definitions/gherkin_steps.rb +29 -0
  24. data/features/step_definitions/json_formatter_steps.rb +28 -0
  25. data/features/step_definitions/json_parser_steps.rb +20 -0
  26. data/features/step_definitions/pretty_formatter_steps.rb +82 -0
  27. data/features/steps_parser.feature +46 -0
  28. data/features/support/env.rb +38 -0
  29. data/gherkin.gemspec +59 -0
  30. data/ikvm/.gitignore +3 -0
  31. data/java/.gitignore +2 -0
  32. data/java/src/main/java/gherkin/lexer/i18n/.gitignore +1 -0
  33. data/java/src/main/resources/gherkin/.gitignore +1 -0
  34. data/lib/.gitignore +4 -0
  35. data/lib/gherkin.rb +2 -0
  36. data/lib/gherkin/c_lexer.rb +17 -0
  37. data/lib/gherkin/cli/main.rb +33 -0
  38. data/lib/gherkin/formatter/argument.rb +28 -0
  39. data/lib/gherkin/formatter/colors.rb +119 -0
  40. data/lib/gherkin/formatter/escaping.rb +15 -0
  41. data/lib/gherkin/formatter/filter_formatter.rb +136 -0
  42. data/lib/gherkin/formatter/json_formatter.rb +72 -0
  43. data/lib/gherkin/formatter/line_filter.rb +26 -0
  44. data/lib/gherkin/formatter/model.rb +231 -0
  45. data/lib/gherkin/formatter/monochrome_format.rb +9 -0
  46. data/lib/gherkin/formatter/pretty_formatter.rb +174 -0
  47. data/lib/gherkin/formatter/regexp_filter.rb +21 -0
  48. data/lib/gherkin/formatter/tag_count_formatter.rb +47 -0
  49. data/lib/gherkin/formatter/tag_filter.rb +19 -0
  50. data/lib/gherkin/i18n.rb +180 -0
  51. data/lib/gherkin/i18n.yml +601 -0
  52. data/lib/gherkin/json_parser.rb +88 -0
  53. data/lib/gherkin/lexer/i18n_lexer.rb +47 -0
  54. data/lib/gherkin/listener/event.rb +45 -0
  55. data/lib/gherkin/listener/formatter_listener.rb +113 -0
  56. data/lib/gherkin/native.rb +7 -0
  57. data/lib/gherkin/native/ikvm.rb +55 -0
  58. data/lib/gherkin/native/java.rb +55 -0
  59. data/lib/gherkin/native/null.rb +9 -0
  60. data/lib/gherkin/parser/meta.txt +5 -0
  61. data/lib/gherkin/parser/parser.rb +164 -0
  62. data/lib/gherkin/parser/root.txt +11 -0
  63. data/lib/gherkin/parser/steps.txt +4 -0
  64. data/lib/gherkin/rb_lexer.rb +8 -0
  65. data/lib/gherkin/rb_lexer/.gitignore +1 -0
  66. data/lib/gherkin/rb_lexer/README.rdoc +8 -0
  67. data/lib/gherkin/rubify.rb +24 -0
  68. data/lib/gherkin/tag_expression.rb +62 -0
  69. data/lib/gherkin/tools.rb +8 -0
  70. data/lib/gherkin/tools/files.rb +34 -0
  71. data/lib/gherkin/tools/reformat.rb +20 -0
  72. data/lib/gherkin/tools/stats.rb +20 -0
  73. data/lib/gherkin/tools/stats_listener.rb +60 -0
  74. data/lib/gherkin/version.rb +3 -0
  75. data/ragel/i18n/.gitignore +1 -0
  76. data/ragel/lexer.c.rl.erb +459 -0
  77. data/ragel/lexer.java.rl.erb +224 -0
  78. data/ragel/lexer.rb.rl.erb +179 -0
  79. data/ragel/lexer_common.rl.erb +50 -0
  80. data/spec/gherkin/c_lexer_spec.rb +21 -0
  81. data/spec/gherkin/fixtures/1.feature +8 -0
  82. data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
  83. data/spec/gherkin/fixtures/complex.feature +45 -0
  84. data/spec/gherkin/fixtures/complex.json +143 -0
  85. data/spec/gherkin/fixtures/complex_for_filtering.feature +60 -0
  86. data/spec/gherkin/fixtures/complex_with_tags.feature +61 -0
  87. data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
  88. data/spec/gherkin/fixtures/hantu_pisang.feature +35 -0
  89. data/spec/gherkin/fixtures/i18n_fr.feature +14 -0
  90. data/spec/gherkin/fixtures/i18n_no.feature +7 -0
  91. data/spec/gherkin/fixtures/i18n_zh-CN.feature +9 -0
  92. data/spec/gherkin/fixtures/scenario_outline_with_tags.feature +13 -0
  93. data/spec/gherkin/fixtures/scenario_without_steps.feature +5 -0
  94. data/spec/gherkin/fixtures/simple_with_comments.feature +7 -0
  95. data/spec/gherkin/fixtures/simple_with_tags.feature +11 -0
  96. data/spec/gherkin/fixtures/with_bom.feature +3 -0
  97. data/spec/gherkin/formatter/argument_spec.rb +28 -0
  98. data/spec/gherkin/formatter/colors_spec.rb +18 -0
  99. data/spec/gherkin/formatter/filter_formatter_spec.rb +165 -0
  100. data/spec/gherkin/formatter/model_spec.rb +15 -0
  101. data/spec/gherkin/formatter/pretty_formatter_spec.rb +140 -0
  102. data/spec/gherkin/formatter/spaces.feature +9 -0
  103. data/spec/gherkin/formatter/tabs.feature +9 -0
  104. data/spec/gherkin/formatter/tag_count_formatter_spec.rb +30 -0
  105. data/spec/gherkin/i18n_spec.rb +149 -0
  106. data/spec/gherkin/java_lexer_spec.rb +20 -0
  107. data/spec/gherkin/json.rb +5 -0
  108. data/spec/gherkin/json_parser_spec.rb +67 -0
  109. data/spec/gherkin/lexer/i18n_lexer_spec.rb +43 -0
  110. data/spec/gherkin/output_stream_string_io.rb +24 -0
  111. data/spec/gherkin/parser/parser_spec.rb +16 -0
  112. data/spec/gherkin/rb_lexer_spec.rb +19 -0
  113. data/spec/gherkin/sexp_recorder.rb +56 -0
  114. data/spec/gherkin/shared/lexer_group.rb +592 -0
  115. data/spec/gherkin/shared/py_string_group.rb +153 -0
  116. data/spec/gherkin/shared/row_group.rb +120 -0
  117. data/spec/gherkin/shared/tags_group.rb +54 -0
  118. data/spec/gherkin/tag_expression_spec.rb +137 -0
  119. data/spec/spec_helper.rb +68 -0
  120. data/tasks/bench.rake +184 -0
  121. data/tasks/bench/feature_builder.rb +49 -0
  122. data/tasks/bench/generated/.gitignore +1 -0
  123. data/tasks/bench/null_listener.rb +4 -0
  124. data/tasks/compile.rake +102 -0
  125. data/tasks/cucumber.rake +18 -0
  126. data/tasks/gems.rake +42 -0
  127. data/tasks/ikvm.rake +54 -0
  128. data/tasks/ragel_task.rb +70 -0
  129. data/tasks/rdoc.rake +9 -0
  130. data/tasks/release.rake +30 -0
  131. data/tasks/rspec.rake +8 -0
  132. metadata +447 -0
@@ -0,0 +1,9 @@
1
+ module Gherkin
2
+ module Formatter
3
+ class MonochromeFormat
4
+ def format_argument(arg)
5
+ arg
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,174 @@
1
+ # encoding: utf-8
2
+ require 'gherkin/formatter/colors'
3
+ require 'gherkin/formatter/monochrome_format'
4
+ require 'gherkin/formatter/argument'
5
+ require 'gherkin/formatter/escaping'
6
+ require 'gherkin/formatter/model'
7
+ require 'gherkin/native'
8
+
9
+ module Gherkin
10
+ module Formatter
11
+ class PrettyFormatter
12
+ native_impl('gherkin')
13
+
14
+ include Colors
15
+ include Escaping
16
+
17
+ def initialize(io, monochrome)
18
+ @io = io
19
+ @monochrome = monochrome
20
+ @format = MonochromeFormat.new #@monochrome ? MonochromeFormat.new : AnsiColorFormat.new
21
+ end
22
+
23
+ def uri(uri)
24
+ @uri = uri
25
+ end
26
+
27
+ def feature(feature)
28
+ print_comments(feature.comments, '')
29
+ print_tags(feature.tags, '')
30
+ @io.puts "#{feature.keyword}: #{feature.name}"
31
+ print_description(feature.description, ' ', false)
32
+ end
33
+
34
+ def background(statement)
35
+ @io.puts
36
+ print_comments(statement.comments, ' ')
37
+ @io.puts " #{statement.keyword}: #{statement.name}#{indented_element_uri!(statement.keyword, statement.name, statement.line)}"
38
+ print_description(statement.description, ' ')
39
+ end
40
+
41
+ def scenario(statement)
42
+ @io.puts
43
+ print_comments(statement.comments, ' ')
44
+ print_tags(statement.tags, ' ')
45
+ @io.puts " #{statement.keyword}: #{statement.name}#{indented_element_uri!(statement.keyword, statement.name, statement.line)}"
46
+ print_description(statement.description, ' ')
47
+ end
48
+
49
+ def scenario_outline(scenario_outline)
50
+ scenario(scenario_outline)
51
+ end
52
+
53
+ def examples(examples)
54
+ @io.puts
55
+ print_comments(examples.comments, ' ')
56
+ print_tags(examples.tags, ' ')
57
+ @io.puts " #{examples.keyword}: #{examples.name}"
58
+ print_description(examples.description, ' ')
59
+ table(examples.rows)
60
+ end
61
+
62
+ def step(step)
63
+ name = Gherkin::Formatter::Argument.format(step.name, @format, (step.result ? step.result.arguments : []))
64
+
65
+ step_text = "#{step.keyword}#{step.name}"
66
+ step_text = self.__send__(step.result.status, step_text, @monochrome) if step.result
67
+
68
+ print_comments(step.comments, ' ')
69
+ @io.puts(" #{step_text}#{indented_step_location!(step.result ? step.result.stepdef_location : nil)}")
70
+ case step.multiline_arg
71
+ when Model::PyString
72
+ py_string(step.multiline_arg)
73
+ when Array
74
+ table(step.multiline_arg)
75
+ end
76
+ end
77
+
78
+ def eof
79
+ # NO-OP
80
+ end
81
+
82
+ # This method can be invoked before a #scenario, to ensure location arguments are aligned
83
+ def steps(steps)
84
+ @step_lengths = steps.map {|keyword, name| (keyword+name).unpack("U*").length}
85
+ @max_step_length = @step_lengths.max
86
+ @step_index = -1
87
+ end
88
+
89
+ def table(rows)
90
+ cell_lengths = rows.map do |row|
91
+ row.cells.map do |cell|
92
+ escape_cell(cell).unpack("U*").length
93
+ end
94
+ end
95
+ max_lengths = cell_lengths.transpose.map { |col_lengths| col_lengths.max }.flatten
96
+
97
+ rows.each_with_index do |row, i|
98
+ row.comments.each do |comment|
99
+ @io.puts " #{comment.value}"
100
+ end
101
+ j = -1
102
+ @io.puts ' | ' + row.cells.zip(max_lengths).map { |cell, max_length|
103
+ j += 1
104
+ color(cell, nil, j) + ' ' * (max_length - cell_lengths[i][j])
105
+ }.join(' | ') + ' |'
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def py_string(py_string)
112
+ @io.puts " \"\"\"\n" + escape_triple_quotes(indent(py_string.value, ' ')) + "\n \"\"\""
113
+ end
114
+
115
+ def exception(exception)
116
+ exception_text = "#{exception.message} (#{exception.class})\n#{(exception.backtrace || []).join("\n")}".gsub(/^/, ' ')
117
+ @io.puts(failed(exception_text, @monochrome))
118
+ end
119
+
120
+ def color(cell, statuses, col)
121
+ if statuses
122
+ self.__send__(statuses[col], escape_cell(cell), @monochrome) + (@monochrome ? '' : reset)
123
+ else
124
+ escape_cell(cell)
125
+ end
126
+ end
127
+
128
+ if(RUBY_VERSION =~ /^1\.9/)
129
+ START = /#{'^'.encode('UTF-8')}/
130
+ TRIPLE_QUOTES = /#{'"""'.encode('UTF-8')}/
131
+ else
132
+ START = /^/
133
+ TRIPLE_QUOTES = /"""/
134
+ end
135
+
136
+ def indent(string, indentation)
137
+ string.gsub(START, indentation)
138
+ end
139
+
140
+ def escape_triple_quotes(s)
141
+ s.gsub(TRIPLE_QUOTES, '\"\"\"')
142
+ end
143
+
144
+ def print_tags(tags, indent)
145
+ @io.write(tags.empty? ? '' : indent + tags.map{|tag| tag.name}.join(' ') + "\n")
146
+ end
147
+
148
+ def print_comments(comments, indent)
149
+ @io.write(comments.empty? ? '' : indent + comments.map{|comment| comment.value}.join("\n#{indent}") + "\n")
150
+ end
151
+
152
+ def print_description(description, indent, newline=true)
153
+ if description != ""
154
+ @io.puts indent(description, indent)
155
+ @io.puts if newline
156
+ end
157
+ end
158
+
159
+ def indented_element_uri!(keyword, name, line)
160
+ return '' if @max_step_length.nil?
161
+ l = (keyword+name).unpack("U*").length
162
+ @max_step_length = [@max_step_length, l].max
163
+ indent = @max_step_length - l
164
+ ' ' * indent + ' ' + comments("# #{@uri}:#{line}", @monochrome)
165
+ end
166
+
167
+ def indented_step_location!(location)
168
+ return '' if location.nil?
169
+ indent = @max_step_length - @step_lengths[@step_index+=1]
170
+ ' ' * indent + ' ' + comments("# #{location}", @monochrome)
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,21 @@
1
+ module Gherkin
2
+ module Formatter
3
+ class RegexpFilter
4
+ def initialize(regexen)
5
+ @regexen = regexen
6
+ end
7
+
8
+ def eval(tags, names, ranges)
9
+ @regexen.detect do |regexp|
10
+ names.detect do |name|
11
+ name =~ regexp
12
+ end
13
+ end
14
+ end
15
+
16
+ def filter_table_body_rows(rows)
17
+ rows
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ module Gherkin
2
+ module Formatter
3
+ class TagCountFormatter
4
+ def initialize(formatter, tag_counts)
5
+ @formatter = formatter
6
+ @tag_counts = tag_counts
7
+ end
8
+
9
+ def uri(uri)
10
+ @uri = uri
11
+ end
12
+
13
+ def feature(feature)
14
+ @feature_tags = feature.tags
15
+ @formatter.feature(feature)
16
+ end
17
+
18
+ def scenario(scenario)
19
+ record_tags((@feature_tags.to_a + scenario.tags.to_a).uniq, scenario.line)
20
+ @formatter.scenario(scenario)
21
+ end
22
+
23
+ def scenario_outline(scenario_outline)
24
+ @scenario_outline_tags = scenario_outline.tags
25
+ @formatter.scenario_outline(scenario_outline)
26
+ end
27
+
28
+ def examples(examples)
29
+ record_tags((@feature_tags.to_a + @scenario_outline_tags.to_a + examples.tags.to_a).uniq, examples.line)
30
+ @formatter.examples(examples)
31
+ end
32
+
33
+ private
34
+
35
+ def record_tags(tags, line)
36
+ tags.each do |tag|
37
+ @tag_counts[tag.name] ||= []
38
+ @tag_counts[tag.name] << "#{@uri}:#{line}"
39
+ end
40
+ end
41
+
42
+ def method_missing(*args)
43
+ @formatter.__send__(*args)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ require 'gherkin/tag_expression'
2
+
3
+ module Gherkin
4
+ module Formatter
5
+ class TagFilter
6
+ def initialize(tags)
7
+ @tag_expression = TagExpression.new(tags)
8
+ end
9
+
10
+ def eval(tags, names, ranges)
11
+ @tag_expression.eval(tags.uniq.map{|tag| tag.name})
12
+ end
13
+
14
+ def filter_table_body_rows(rows)
15
+ rows
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,180 @@
1
+ require 'yaml'
2
+ require 'gherkin/rubify'
3
+ require 'gherkin/native'
4
+
5
+ module Gherkin
6
+ class I18n
7
+ native_impl('gherkin') unless defined?(BYPASS_NATIVE_IMPL)
8
+
9
+ FEATURE_ELEMENT_KEYS = %w{feature background scenario scenario_outline examples}
10
+ STEP_KEYWORD_KEYS = %w{given when then and but}
11
+ KEYWORD_KEYS = FEATURE_ELEMENT_KEYS + STEP_KEYWORD_KEYS
12
+ LANGUAGES = YAML.load_file(File.dirname(__FILE__) + '/i18n.yml')
13
+
14
+ class << self
15
+ include Rubify
16
+
17
+ # Used by code generators for other lexer tools like pygments lexer and textmate bundle
18
+ def all
19
+ LANGUAGES.keys.sort.map{|iso_code| get(iso_code)}
20
+ end
21
+
22
+ def get(iso_code)
23
+ languages[iso_code] ||= new(iso_code)
24
+ end
25
+
26
+ # Returns all keyword translations and aliases of +keywords+, escaped and joined with <tt>|</tt>.
27
+ # This method is convenient for editor support and syntax highlighting engines for Gherkin, where
28
+ # there is typically a code generation tool to generate regular expressions for recognising the
29
+ # various I18n translations of Gherkin's keywords.
30
+ #
31
+ # The +keywords+ arguments can be one of <tt>:feature</tt>, <tt>:background</tt>, <tt>:scenario</tt>,
32
+ # <tt>:scenario_outline</tt>, <tt>:examples</tt>, <tt>:step</tt>.
33
+ def keyword_regexp(*keywords)
34
+ unique_keywords = all.map do |i18n|
35
+ keywords.map do |keyword|
36
+ if keyword.to_s == 'step'
37
+ i18n.step_keywords.to_a
38
+ else
39
+ i18n.keywords(keyword).to_a
40
+ end
41
+ end
42
+ end
43
+
44
+ unique_keywords.flatten.compact.map{|kw| kw.to_s}.sort.reverse.uniq.join('|').gsub(/\*/, '\*')
45
+ end
46
+
47
+ def code_keywords
48
+ rubify(all.map{|i18n| i18n.code_keywords}).flatten.uniq.sort
49
+ end
50
+
51
+ def code_keyword_for(gherkin_keyword)
52
+ gherkin_keyword.gsub(/[\s',!]/, '').strip
53
+ end
54
+
55
+ def language_table
56
+ require 'stringio'
57
+ require 'gherkin/formatter/pretty_formatter'
58
+ require 'gherkin/formatter/model'
59
+ io = defined?(JRUBY_VERSION) ? Java.java.io.StringWriter.new : StringIO.new
60
+ pf = Gherkin::Formatter::PrettyFormatter.new(io, true)
61
+ table = all.map do |i18n|
62
+ Formatter::Model::Row.new([], [i18n.iso_code, i18n.keywords('name')[0], i18n.keywords('native')[0]], nil)
63
+ end
64
+ pf.table(table)
65
+ if defined?(JRUBY_VERSION)
66
+ io.getBuffer.toString
67
+ else
68
+ io.string
69
+ end
70
+ end
71
+
72
+ def unicode_escape(word, prefix="\\u")
73
+ word = word.unpack("U*").map do |c|
74
+ if c > 127 || c == 32
75
+ "#{prefix}%04x" % c
76
+ else
77
+ c.chr
78
+ end
79
+ end.join
80
+ end
81
+
82
+ private
83
+
84
+ def languages
85
+ @languages ||= {}
86
+ end
87
+ end
88
+
89
+ attr_reader :iso_code
90
+
91
+ def initialize(iso_code)
92
+ @iso_code = iso_code
93
+ @keywords = LANGUAGES[iso_code]
94
+ raise "Language not supported: #{iso_code.inspect}" if @iso_code.nil?
95
+ @keywords['grammar_name'] = @keywords['name'].gsub(/\s/, '')
96
+ end
97
+
98
+ def lexer(listener, force_ruby=false)
99
+ begin
100
+ if force_ruby
101
+ rb(listener)
102
+ else
103
+ begin
104
+ c(listener)
105
+ rescue NameError, LoadError => e
106
+ warn("WARNING: #{e.message}. Reverting to Ruby lexer.")
107
+ rb(listener)
108
+ end
109
+ end
110
+ rescue LoadError => e
111
+ raise I18nLexerNotFound, "No lexer was found for #{i18n_language_name} (#{e.message}). Supported languages are listed in gherkin/i18n.yml."
112
+ end
113
+ end
114
+
115
+ def c(listener)
116
+ require 'gherkin/c_lexer'
117
+ CLexer[underscored_iso_code].new(listener)
118
+ end
119
+
120
+ def rb(listener)
121
+ require 'gherkin/rb_lexer'
122
+ RbLexer[underscored_iso_code].new(listener)
123
+ end
124
+
125
+ def underscored_iso_code
126
+ @iso_code.gsub(/[\s-]/, '_').downcase
127
+ end
128
+
129
+ # Keywords that can be used in Gherkin source
130
+ def step_keywords
131
+ STEP_KEYWORD_KEYS.map{|iso_code| keywords(iso_code)}.flatten.uniq
132
+ end
133
+
134
+ # Keywords that can be used in code
135
+ def code_keywords
136
+ result = step_keywords.map{|keyword| self.class.code_keyword_for(keyword)}
137
+ result.delete('*')
138
+ result
139
+ end
140
+
141
+ def keywords(key)
142
+ key = key.to_s
143
+ raise "No #{key.inspect} in #{@keywords.inspect}" if @keywords[key].nil?
144
+ @keywords[key].split('|').map{|keyword| real_keyword(key, keyword)}
145
+ end
146
+
147
+ def keyword_table
148
+ require 'stringio'
149
+ require 'gherkin/formatter/pretty_formatter'
150
+ require 'gherkin/formatter/model'
151
+ io = StringIO.new
152
+ pf = Gherkin::Formatter::PrettyFormatter.new(io, true)
153
+
154
+ gherkin_keyword_table = KEYWORD_KEYS.map do |key|
155
+ Formatter::Model::Row.new([], [key, keywords(key).map{|keyword| %{"#{keyword}"}}.join(', ')], nil)
156
+ end
157
+
158
+ code_keyword_table = STEP_KEYWORD_KEYS.map do |key|
159
+ code_keywords = keywords(key).reject{|keyword| keyword == '* '}.map do |keyword|
160
+ %{"#{self.class.code_keyword_for(keyword)}"}
161
+ end.join(', ')
162
+ Formatter::Model::Row.new([], ["#{key} (code)", code_keywords], nil)
163
+ end
164
+
165
+ pf.table(gherkin_keyword_table + code_keyword_table)
166
+ io.rewind
167
+ io.read
168
+ end
169
+
170
+ private
171
+
172
+ def real_keyword(key, keyword)
173
+ if(STEP_KEYWORD_KEYS.index(key))
174
+ (keyword + ' ').sub(/< $/, '')
175
+ else
176
+ keyword
177
+ end
178
+ end
179
+ end
180
+ end