asker-tool 2.5.9 → 2.7.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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -7
  3. data/lib/asker/ai/ai.rb +17 -22
  4. data/lib/asker/ai/ai_calculate.rb +10 -17
  5. data/lib/asker/ai/code/base_code_ai.rb +5 -30
  6. data/lib/asker/ai/code/code_ai_factory.rb +6 -12
  7. data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
  8. data/lib/asker/ai/code/python_code_ai.rb +35 -36
  9. data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
  10. data/lib/asker/ai/code/sql_code_ai.rb +20 -21
  11. data/lib/asker/ai/concept_ai.rb +12 -22
  12. data/lib/asker/ai/problem/problem_ai.rb +226 -0
  13. data/lib/asker/ai/question.rb +34 -45
  14. data/lib/asker/ai/stages/base_stage.rb +7 -7
  15. data/lib/asker/ai/stages/main.rb +6 -7
  16. data/lib/asker/ai/stages/stage_b.rb +62 -28
  17. data/lib/asker/ai/stages/stage_d.rb +10 -10
  18. data/lib/asker/ai/stages/stage_f.rb +17 -17
  19. data/lib/asker/ai/stages/stage_i.rb +8 -18
  20. data/lib/asker/ai/stages/stage_s.rb +28 -26
  21. data/lib/asker/ai/stages/stage_t.rb +54 -76
  22. data/lib/asker/application.rb +15 -14
  23. data/lib/asker/check_input/check_haml_data.rb +57 -51
  24. data/lib/asker/check_input/check_table.rb +26 -19
  25. data/lib/asker/check_input.rb +10 -22
  26. data/lib/asker/cli.rb +43 -24
  27. data/lib/asker/data/code.rb +10 -9
  28. data/lib/asker/data/column.rb +21 -17
  29. data/lib/asker/data/concept.rb +24 -37
  30. data/lib/asker/data/data_field.rb +2 -2
  31. data/lib/asker/data/problem.rb +112 -0
  32. data/lib/asker/data/project_data.rb +11 -15
  33. data/lib/asker/data/row.rb +25 -23
  34. data/lib/asker/data/table.rb +25 -46
  35. data/lib/asker/data/template.rb +7 -7
  36. data/lib/asker/data/world.rb +3 -3
  37. data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
  38. data/lib/asker/displayer/code_displayer.rb +10 -10
  39. data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
  40. data/lib/asker/displayer/concept_ai_displayer.rb +22 -34
  41. data/lib/asker/displayer/concept_displayer.rb +9 -11
  42. data/lib/asker/displayer/problem_displayer.rb +45 -0
  43. data/lib/asker/displayer/stats_displayer.rb +7 -12
  44. data/lib/asker/exporter/code_gift_exporter.rb +2 -2
  45. data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
  46. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
  47. data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
  48. data/lib/asker/exporter/data_gift_exporter.rb +14 -15
  49. data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
  50. data/lib/asker/exporter/output_file_exporter.rb +9 -8
  51. data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
  52. data/lib/asker/files/language/ca/templates.yaml +6 -0
  53. data/lib/asker/files/language/du/templates.yaml +6 -0
  54. data/lib/asker/files/language/en/templates.yaml +7 -1
  55. data/lib/asker/files/language/es/templates.yaml +6 -0
  56. data/lib/asker/files/language/fr/templates.yaml +6 -0
  57. data/lib/asker/formatter/code_string_formatter.rb +5 -5
  58. data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
  59. data/lib/asker/formatter/concept_string_formatter.rb +27 -24
  60. data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
  61. data/lib/asker/formatter/moodle/gapfill.erb +57 -0
  62. data/lib/asker/formatter/moodle/ordering.erb +41 -0
  63. data/lib/asker/formatter/question_gift_formatter.rb +41 -14
  64. data/lib/asker/formatter/question_hash_formatter.rb +5 -6
  65. data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
  66. data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
  67. data/lib/asker/lang/lang.rb +16 -16
  68. data/lib/asker/lang/lang_factory.rb +13 -16
  69. data/lib/asker/lang/text_actions.rb +20 -18
  70. data/lib/asker/loader/code_loader.rb +10 -22
  71. data/lib/asker/loader/content_loader.rb +42 -49
  72. data/lib/asker/loader/directory_loader.rb +13 -16
  73. data/lib/asker/loader/embedded_file.rb +29 -24
  74. data/lib/asker/loader/file_loader.rb +7 -6
  75. data/lib/asker/loader/haml_loader.rb +6 -5
  76. data/lib/asker/loader/image_url_loader.rb +21 -18
  77. data/lib/asker/loader/input_loader.rb +27 -14
  78. data/lib/asker/loader/problem_loader.rb +88 -0
  79. data/lib/asker/loader/project_loader.rb +11 -28
  80. data/lib/asker/logger.rb +22 -13
  81. data/lib/asker/skeleton.rb +27 -43
  82. data/lib/asker/start.rb +44 -0
  83. data/lib/asker/version.rb +1 -1
  84. data/lib/asker.rb +7 -53
  85. metadata +12 -20
  86. data/lib/asker/ai/code/problem_code_ai.rb +0 -176
  87. data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
  88. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
@@ -1,20 +1,15 @@
1
- # frozen_string_literal: true
2
-
3
- require 'set'
4
- require_relative 'base_stage'
5
- require_relative '../question'
1
+ require "set"
2
+ require_relative "base_stage"
3
+ require_relative "../question"
6
4
 
7
5
  ##
8
6
  # StageT create questions based con Table data
9
7
  # range t1-t9
10
- # rubocop:disable Metrics/ClassLength
11
8
  class StageT < BaseStage
12
9
  # process_tableXfields
13
- # rubocop:disable Metrics/MethodLength
14
- # rubocop:disable Metrics/AbcSize
15
10
  def run(table, row, list)
16
11
  questions = []
17
- return questions unless concept.type == 'text'
12
+ return questions unless concept.type == "text"
18
13
 
19
14
  if table.fields.count == 2
20
15
  questions += process_table2fields(table, row, list, 0, 1)
@@ -29,19 +24,12 @@ class StageT < BaseStage
29
24
 
30
25
  questions
31
26
  end
32
- # rubocop:enable Metrics/MethodLength
33
- # rubocop:enable Metrics/AbcSize
34
27
 
35
28
  private
36
29
 
37
- # rubocop:disable Metrics/MethodLength
38
- # rubocop:disable Metrics/AbcSize
39
- # rubocop:disable Metrics/CyclomaticComplexity
40
- # rubocop:disable Metrics/PerceivedComplexity
41
30
  def process_table2fields(table, row, list, col1, col2)
42
31
  questions = []
43
32
  lang = concept.lang
44
- # create questions
45
33
 
46
34
  # Question choice: Using the column #0
47
35
  s = Set.new [row[:data][col1], lang.text_for(:none)]
@@ -49,11 +37,11 @@ class StageT < BaseStage
49
37
  a = s.to_a
50
38
 
51
39
  if s.count > 3
52
- q = Question.new
40
+ q = Question.new(:choice)
53
41
  q.name = "#{name}-#{num}-t1table-#{table.name}"
54
42
  q.text = random_image_for(name) \
55
- + lang.text_for(:t1table, name, table.fields[col1].capitalize, \
56
- table.fields[col2].capitalize, row[:data][col2])
43
+ + lang.text_for(:t1table, name, table.fields[col1].capitalize,
44
+ table.fields[col2].capitalize, row[:data][col2])
57
45
  q.good = row[:data][col1]
58
46
  q.bads << lang.text_for(:none)
59
47
  q.bads << a[2]
@@ -61,16 +49,17 @@ class StageT < BaseStage
61
49
  questions << q
62
50
  end
63
51
 
64
- s = Set.new [row[:data][col1], lang.text_for(:none)]
65
- list.each { |i| s.add(i[:data][col1]) }
66
- a = s.to_a
52
+ # REPETIDO???
53
+ # s = Set.new [row[:data][col1], lang.text_for(:none)]
54
+ # list.each { |i| s.add(i[:data][col1]) }
55
+ # a = s.to_a
67
56
 
68
57
  if s.count > 4
69
- q = Question.new
58
+ q = Question.new(:choice)
70
59
  q.name = "#{name}-#{num}-t2table-#{table.name}"
71
60
  q.text = random_image_for(name) \
72
- + lang.text_for(:t2table, name, table.fields[col1].capitalize, \
73
- table.fields[col2].capitalize, row[:data][col2])
61
+ + lang.text_for(:t2table, name, table.fields[col1].capitalize,
62
+ table.fields[col2].capitalize, row[:data][col2])
74
63
  q.good = lang.text_for(:none)
75
64
  q.bads << a[2]
76
65
  q.bads << a[3]
@@ -84,11 +73,11 @@ class StageT < BaseStage
84
73
  a = s.to_a
85
74
 
86
75
  if s.count > 3
87
- q = Question.new
76
+ q = Question.new(:choice)
88
77
  q.name = "#{name}-#{num}-t3table-#{table.name}"
89
78
  q.text = random_image_for(name) \
90
- + lang.text_for(:t3table, name, table.fields[col1].capitalize, \
91
- row[:data][col1], table.fields[col2].capitalize)
79
+ + lang.text_for(:t3table, name, table.fields[col1].capitalize,
80
+ row[:data][col1], table.fields[col2].capitalize)
92
81
  q.good = a[0]
93
82
  q.bads << lang.text_for(:none)
94
83
  q.bads << a[2]
@@ -96,16 +85,17 @@ class StageT < BaseStage
96
85
  questions << q
97
86
  end
98
87
 
99
- s = Set.new [row[:data][col2], lang.text_for(:none)]
100
- list.each { |i| s.add(i[:data][col2]) }
101
- a = s.to_a
88
+ # REPTIDO???
89
+ # s = Set.new [row[:data][col2], lang.text_for(:none)]
90
+ # list.each { |i| s.add(i[:data][col2]) }
91
+ # a = s.to_a
102
92
 
103
93
  if s.count > 4
104
- q = Question.new
94
+ q = Question.new(:choice)
105
95
  q.name = "#{name}-#{num}-t4table-#{table.name}"
106
96
  q.text = random_image_for(name) \
107
- + lang.text_for(:t4table, name, table.fields[col1].capitalize, \
108
- row[:data][col1], table.fields[col2].capitalize)
97
+ + lang.text_for(:t4table, name, table.fields[col1].capitalize,
98
+ row[:data][col1], table.fields[col2].capitalize)
109
99
  q.good = lang.text_for(:none)
110
100
  q.bads << a[2]
111
101
  q.bads << a[3]
@@ -114,13 +104,12 @@ class StageT < BaseStage
114
104
  end
115
105
 
116
106
  # Question Boolean: TRUE
117
- q = Question.new
118
- q.set_boolean
107
+ q = Question.new(:boolean)
119
108
  q.name = "#{name}-#{num}t5table-#{table.name}"
120
109
  q.text = random_image_for(name) \
121
- + lang.text_for(:t5table, name, table.fields[col1].capitalize, \
122
- row[:data][col1], table.fields[col2].capitalize, row[:data][col2])
123
- q.good = 'TRUE'
110
+ + lang.text_for(:t5table, name, table.fields[col1].capitalize,
111
+ row[:data][col1], table.fields[col2].capitalize, row[:data][col2])
112
+ q.good = "TRUE"
124
113
  questions << q
125
114
 
126
115
  # Question Boolean: FALSE
@@ -129,13 +118,12 @@ class StageT < BaseStage
129
118
  a = s.to_a
130
119
 
131
120
  if s.count > 1
132
- q = Question.new
133
- q.set_boolean
121
+ q = Question.new(:boolean)
134
122
  q.name = "#{name}-#{num}-t6table-#{table.name}"
135
123
  q.text = random_image_for(name) \
136
- + lang.text_for(:t6table, name, table.fields[col1].capitalize, \
137
- row[:data][col1], table.fields[col2].capitalize, a[1])
138
- q.good = 'FALSE'
124
+ + lang.text_for(:t6table, name, table.fields[col1].capitalize,
125
+ row[:data][col1], table.fields[col2].capitalize, a[1])
126
+ q.good = "FALSE"
139
127
  questions << q
140
128
  end
141
129
 
@@ -144,68 +132,58 @@ class StageT < BaseStage
144
132
  a = s.to_a
145
133
 
146
134
  if s.count > 1
147
- q = Question.new
148
- q.set_boolean
135
+ q = Question.new(:boolean)
149
136
  q.name = "#{name}-#{num}t7table-#{table.name}"
150
137
  q.text = random_image_for(name) \
151
- + lang.text_for(:t7table, name, table.fields[col1].capitalize, \
152
- a[1], table.fields[col2].capitalize, row[:data][col2])
153
- q.good = 'FALSE'
138
+ + lang.text_for(:t7table, name, table.fields[col1].capitalize,
139
+ a[1], table.fields[col2].capitalize, row[:data][col2])
140
+ q.good = "FALSE"
154
141
  questions << q
155
142
  end
156
143
 
157
144
  # Question Short: column #0, 1 word
158
145
  if lang.count_words(row[:data][col1]) == 1
159
- q = Question.new
160
- q.set_short
146
+ q = Question.new(:short)
161
147
  q.name = "#{name}-#{num}t8table-#{table.name}"
162
148
  q.text = random_image_for(name) \
163
- + lang.text_for(:t8table, name, table.fields[col2].capitalize, \
164
- row[:data][col2], table.fields[col1].capitalize)
149
+ + lang.text_for(:t8table, name, table.fields[col2].capitalize,
150
+ row[:data][col2], table.fields[col1].capitalize)
165
151
  q.shorts << row[:data][col1]
166
- q.shorts << row[:data][col1].gsub('-', ' ').gsub('_', ' ')
152
+ q.shorts << row[:data][col1].tr("-", " ").tr("_", " ")
167
153
  questions << q
168
154
  elsif lang.count_words(row[:data][col1]) == 2
169
- q = Question.new
170
- q.set_short
155
+ q = Question.new(:short)
171
156
  q.name = "#{name}-#{num}t9table-#{table.name}"
172
157
  q.text = random_image_for(name) \
173
- + lang.text_for(:t9table, name, table.fields[col2].capitalize, \
174
- row[:data][col2], table.fields[col1].capitalize, \
175
- "[#{lang.hide_text(row[:data][col1])}]", lang.count_words(row[:data][col1]))
158
+ + lang.text_for(:t9table, name, table.fields[col2].capitalize,
159
+ row[:data][col2], table.fields[col1].capitalize,
160
+ "[#{lang.hide_text(row[:data][col1])}]", lang.count_words(row[:data][col1]))
176
161
  q.shorts << row[:data][col1]
177
- q.shorts << row[:data][col1].gsub('-', ' ').gsub('_', ' ')
162
+ q.shorts << row[:data][col1].tr("-", " ").tr("_", " ")
178
163
  questions << q
179
164
  end
180
165
 
181
166
  # Question Short: column #1, 1 word
182
167
  if lang.count_words(row[:data][col2]) == 1
183
- q = Question.new
184
- q.set_short
168
+ q = Question.new(:short)
185
169
  q.name = "#{name}-#{num}t8table-#{table.name}"
186
170
  q.text = random_image_for(name) \
187
- + lang.text_for(:t8table, name, table.fields[col1].capitalize, \
188
- row[:data][col1], table.fields[col2].capitalize)
171
+ + lang.text_for(:t8table, name, table.fields[col1].capitalize,
172
+ row[:data][col1], table.fields[col2].capitalize)
189
173
  q.shorts << row[:data][col2]
190
- q.shorts << row[:data][col2].gsub('-', ' ').gsub('_', ' ')
174
+ q.shorts << row[:data][col2].tr("-", " ").tr("_", " ")
191
175
  questions << q
192
176
  elsif lang.count_words(row[:data][col2]) == 2
193
- q = Question.new
194
- q.set_short
177
+ q = Question.new(:short)
195
178
  q.name = "#{name}-#{num}t9table-#{table.name}"
196
179
  q.text = random_image_for(name) \
197
- + lang.text_for(:t9table, name, table.fields[col1].capitalize, \
198
- row[:data][col1], table.fields[col2].capitalize, \
199
- "[#{lang.hide_text(row[:data][col2])}]", lang.count_words(row[:data][col2]))
180
+ + lang.text_for(:t9table, name, table.fields[col1].capitalize,
181
+ row[:data][col1], table.fields[col2].capitalize,
182
+ "[#{lang.hide_text(row[:data][col2])}]", lang.count_words(row[:data][col2]))
200
183
  q.shorts << row[:data][col2]
201
- q.shorts << row[:data][col2].gsub('-', ' ').gsub('_', ' ')
184
+ q.shorts << row[:data][col2].tr("-", " ").tr("_", " ")
202
185
  questions << q
203
186
  end
204
187
  questions
205
188
  end
206
- # rubocop:enable Metrics/MethodLength
207
- # rubocop:enable Metrics/AbcSize
208
- # rubocop:enable Metrics/CyclomaticComplexity
209
- # rubocop:enable Metrics/PerceivedComplexity
210
189
  end
211
- # rubocop:enable Metrics/ClassLength
@@ -1,6 +1,6 @@
1
1
  require "singleton"
2
2
  require "inifile"
3
- require "rainbow"
3
+ require_relative "logger"
4
4
  require_relative "version"
5
5
 
6
6
  # Global parameters
@@ -14,26 +14,27 @@ class Application
14
14
 
15
15
  def reset
16
16
  filename = File.join(Dir.pwd,
17
- Asker::CONFIGFILE)
18
- filename = File.join(File.dirname(__FILE__),
19
- 'files',
20
- Asker::CONFIGFILE) unless File.exist? filename
17
+ Asker::CONFIGFILE)
18
+ unless File.exist? filename
19
+ filename = File.join(File.dirname(__FILE__),
20
+ "files",
21
+ Asker::CONFIGFILE)
22
+ end
21
23
 
22
24
  begin
23
25
  @config = IniFile.load(filename)
24
- rescue StandardError => e
25
- puts e.display
26
- puts Rainbow('[ERROR] Revise configuration file:').red.bright
27
- puts Rainbow(" #{filename}").red.bright
26
+ rescue => e
27
+ Logger.error e.display
28
+ Logger.error "Application: Revise configuration file (#{filename})"
28
29
  exit 1
29
30
  end
30
- stages = @config['questions']['stages'].split(',')
31
- @config['questions']['stages'] = stages.map(&:to_sym)
31
+ stages = @config["questions"]["stages"].split(",")
32
+ @config["questions"]["stages"] = stages.map(&:to_sym)
32
33
 
33
- fractions = @config['questions']['fractions'].split(',')
34
- @config['questions']['fractions'] = fractions + Array.new(5, '0')
34
+ fractions = @config["questions"]["fractions"].split(",")
35
+ @config["questions"]["fractions"] = fractions + Array.new(5, "0")
35
36
 
36
37
  Rainbow.enabled = false
37
- Rainbow.enabled = true if @config['global']['color'].downcase == 'yes'
38
+ Rainbow.enabled = true if @config["global"]["color"].downcase == "yes"
38
39
  end
39
40
  end
@@ -1,4 +1,3 @@
1
- require "colorize"
2
1
  require_relative "check_table"
3
2
 
4
3
  class CheckHamlData
@@ -9,19 +8,19 @@ class CheckHamlData
9
8
  @inputs = File.read(filepath).split("\n")
10
9
  @outputs = []
11
10
  @inputs.each_with_index do |line, index|
12
- output = { id: index,
13
- level: 0,
14
- state: :none,
15
- type: :none,
16
- source: line,
17
- msg: '' }
11
+ output = {id: index,
12
+ level: 0,
13
+ state: :none,
14
+ type: :none,
15
+ source: line,
16
+ msg: ""}
18
17
  @outputs << output
19
18
  end
20
19
  @ok = false
21
20
  end
22
21
 
23
22
  def ok?
24
- @ok
23
+ @ok
25
24
  end
26
25
 
27
26
  def show
@@ -32,25 +31,29 @@ class CheckHamlData
32
31
 
33
32
  def show_errors
34
33
  errors = 0
35
- puts "\n"
36
34
  @outputs.each do |i|
37
35
  next if i[:state] == :ok
38
36
 
39
37
  errors += 1
40
38
  if errors < 11
41
- data = { id: i[:id], msg: i[:msg], source: i[:source][0, 40] }
39
+ data = {id: i[:id], msg: i[:msg], source: i[:source][0, 40]}
42
40
  order = i[:id] + 1
43
- data = { order: order, msg: i[:msg], source: i[:source][0, 40] }
44
- print format(' %<order>03d : %<msg>32s. => '.white, data)
45
- puts format('%<source>s'.light_yellow, data)
41
+ data = {order: order, msg: i[:msg], source: i[:source][0, 40]}
42
+ message1 = Rainbow(" %<order>03d : %<msg>32s. => ").white
43
+ message2 = Rainbow("%<source>s").yellow.bright
44
+ output = format(message1, data) + format(message2, data)
45
+ warn output
46
46
  end
47
- puts '...' if errors == 11
47
+ warn "..." if errors == 11
48
48
  end
49
49
 
50
- if errors.positive?
51
- puts "\n[ ASKER ] Please! Revise #{errors.to_s.light_red} error/s\n"
50
+ if errors.zero?
51
+ puts Rainbow("Syntax OK!").green.bright
52
+ else
53
+ message = "\nRevise #{errors} syntax warning or error/s\n"
54
+ warn Rainbow(message).yellow.bright
55
+ exit 1
52
56
  end
53
- puts 'Syntax OK!'.green if errors.zero?
54
57
  end
55
58
 
56
59
  def check
@@ -80,7 +83,7 @@ class CheckHamlData
80
83
  private
81
84
 
82
85
  def check_empty_lines(line, index)
83
- return unless line.strip.size.zero? || line.start_with?('#')
86
+ return unless line.strip.size.zero? || line.start_with?("#")
84
87
 
85
88
  @outputs[index][:type] = :empty
86
89
  @outputs[index][:level] = -1
@@ -90,152 +93,155 @@ class CheckHamlData
90
93
  def check_map(line, index)
91
94
  if index.zero?
92
95
  @outputs[index][:type] = :map
93
- if line.start_with?('%map{')
96
+ if line.start_with?("%map{")
94
97
  @outputs[index][:state] = :ok
95
98
  else
96
99
  @outputs[index][:state] = :err
97
- @outputs[index][:msg] = 'Start with %map{'
100
+ @outputs[index][:msg] = "Start with %map{"
98
101
  end
99
- elsif index.positive? && line.include?('%map{')
102
+ elsif index.positive? && line.include?("%map{")
100
103
  @outputs[index][:state] = :err
101
104
  @outputs[index][:type] = :map
102
- @outputs[index][:msg] = 'Write %map on line 0'
105
+ @outputs[index][:msg] = "Write %map on line 0"
103
106
  end
104
107
  end
105
108
 
106
109
  def check_concept(line, index)
107
110
  return unless @outputs[index][:state] == :none
108
- return unless line.include? '%concept'
111
+ return unless line.include? "%concept"
109
112
 
110
113
  @outputs[index][:type] = :concept
111
114
  @outputs[index][:level] = 1
112
115
  @outputs[index][:state] = :ok
113
116
  if find_parent(index) != :map
114
117
  @outputs[index][:state] = :err
115
- @outputs[index][:msg] = 'Parent(map) not found!'
118
+ @outputs[index][:msg] = "Parent(map) not found!"
116
119
  elsif !line.match(/^\s\s%concept\s*$/)
117
120
  binding.break
118
121
  @outputs[index][:state] = :err
119
- @outputs[index][:msg] = 'Write 2 spaces before %concept, and no text after'
122
+ @outputs[index][:msg] = "Write 2 spaces before %concept, and no text after"
120
123
  end
121
124
  end
122
125
 
123
126
  def check_names(line, index)
124
127
  return unless @outputs[index][:state] == :none
125
- return unless line.include? '%names'
128
+ return unless line.include? "%names"
126
129
 
127
130
  @outputs[index][:type] = :names
128
131
  @outputs[index][:level] = 2
129
132
  @outputs[index][:state] = :ok
130
133
  if find_parent(index) != :concept
131
134
  @outputs[index][:state] = :err
132
- @outputs[index][:msg] = 'Parent(concept) not found!'
133
- elsif !line.start_with? ' %names'
135
+ @outputs[index][:msg] = "Parent(concept) not found!"
136
+ elsif !line.start_with? " %names"
134
137
  elsif !line.match(/^\s\s\s\s%names\s/)
135
138
  @outputs[index][:state] = :err
136
- @outputs[index][:msg] = 'Write 4 spaces before %names'
139
+ @outputs[index][:msg] = "Write 4 spaces before %names"
137
140
  end
138
141
  end
139
142
 
140
143
  def check_tags(line, index)
141
144
  return unless @outputs[index][:state] == :none
142
- return unless line.include? '%tags'
145
+ return unless line.include? "%tags"
143
146
 
144
147
  @outputs[index][:type] = :tags
145
148
  @outputs[index][:level] = 2
146
149
  @outputs[index][:state] = :ok
147
- if find_parent(index) != :concept
150
+ if line.strip == "%tags"
151
+ @outputs[index][:state] = :err
152
+ @outputs[index][:msg] = "Please, fill with concept tags!"
153
+ elsif find_parent(index) != :concept
148
154
  @outputs[index][:state] = :err
149
- @outputs[index][:msg] = 'Parent(concept) not found!'
155
+ @outputs[index][:msg] = "Parent(concept) not found!"
150
156
  elsif !line.match(/^\s\s\s\s%tags\s/)
151
157
  @outputs[index][:state] = :err
152
- @outputs[index][:msg] = 'Write 4 spaces before %tags'
158
+ @outputs[index][:msg] = "Write 4 spaces before %tags"
153
159
  end
154
160
  end
155
161
 
156
162
  def check_def(line, index)
157
163
  return unless @outputs[index][:state] == :none
158
- return unless line.include? '%def'
164
+ return unless line.include? "%def"
159
165
 
160
166
  @outputs[index][:type] = :def
161
167
  @outputs[index][:level] = 2
162
168
  @outputs[index][:state] = :ok
163
169
  if find_parent(index) != :concept
164
170
  @outputs[index][:state] = :err
165
- @outputs[index][:msg] = 'Parent(concept) not found!'
171
+ @outputs[index][:msg] = "Parent(concept) not found!"
166
172
  elsif !line.match(/^\s\s\s\s%def[\s{]/)
167
173
  @outputs[index][:state] = :err
168
- @outputs[index][:msg] = 'Write 4 spaces before %def'
174
+ @outputs[index][:msg] = "Write 4 spaces before %def"
169
175
  else
170
176
  items = line.strip.split
171
177
  if items.size < 2
172
178
  @outputs[index][:state] = :err
173
- @outputs[index][:msg] = '%def has no definition'
179
+ @outputs[index][:msg] = "%def has no definition"
174
180
  end
175
181
  end
176
182
  end
177
183
 
178
184
  def check_code(line, index)
179
185
  return unless @outputs[index][:state] == :none
180
- return unless line.include? '%code'
186
+ return unless line.include? "%code"
181
187
 
182
188
  @outputs[index][:type] = :code
183
189
  @outputs[index][:level] = 1
184
190
  @outputs[index][:state] = :ok
185
191
  if find_parent(index) != :map
186
192
  @outputs[index][:state] = :err
187
- @outputs[index][:msg] = 'Parent(map) not found!'
193
+ @outputs[index][:msg] = "Parent(map) not found!"
188
194
  elsif !line.match(/^\s\s%code\s*$/)
189
195
  @outputs[index][:state] = :err
190
- @outputs[index][:msg] = 'Write 2 spaces before %code, and no text after'
196
+ @outputs[index][:msg] = "Write 2 spaces before %code, and no text after"
191
197
  end
192
198
  end
193
199
 
194
200
  def check_type(line, index)
195
201
  return unless @outputs[index][:state] == :none
196
- return unless line.include? '%type'
202
+ return unless line.include? "%type"
197
203
 
198
204
  @outputs[index][:type] = :type
199
205
  @outputs[index][:level] = 2
200
206
  @outputs[index][:state] = :ok
201
207
  if find_parent(index) != :code
202
208
  @outputs[index][:state] = :err
203
- @outputs[index][:msg] = 'Parent(code) not found!'
209
+ @outputs[index][:msg] = "Parent(code) not found!"
204
210
  elsif !line.match(/^\s\s\s\s%type\s/)
205
211
  @outputs[index][:state] = :err
206
- @outputs[index][:msg] = 'Write 4 spaces before %type'
212
+ @outputs[index][:msg] = "Write 4 spaces before %type"
207
213
  end
208
214
  end
209
215
 
210
216
  def check_path(line, index)
211
217
  return unless @outputs[index][:state] == :none
212
- return unless line.include? '%path'
218
+ return unless line.include? "%path"
213
219
 
214
220
  @outputs[index][:type] = :path
215
221
  @outputs[index][:level] = 2
216
222
  @outputs[index][:state] = :ok
217
223
  if find_parent(index) != :code
218
224
  @outputs[index][:state] = :err
219
- @outputs[index][:msg] = 'Parent(code) not found!'
225
+ @outputs[index][:msg] = "Parent(code) not found!"
220
226
  elsif !line.match(/^\s\s\s\s%path\s/)
221
227
  @outputs[index][:state] = :err
222
- @outputs[index][:msg] = 'Write 4 spaces before %type'
228
+ @outputs[index][:msg] = "Write 4 spaces before %type"
223
229
  end
224
230
  end
225
231
 
226
232
  def check_features(line, index)
227
233
  return unless @outputs[index][:state] == :none
228
- return unless line.include? '%features'
234
+ return unless line.include? "%features"
229
235
 
230
236
  @outputs[index][:type] = :features
231
237
  @outputs[index][:level] = 2
232
238
  @outputs[index][:state] = :ok
233
239
  if find_parent(index) != :code
234
240
  @outputs[index][:state] = :err
235
- @outputs[index][:msg] = 'Parent(code) not found!'
241
+ @outputs[index][:msg] = "Parent(code) not found!"
236
242
  elsif !line.match(/^\s\s\s\s%features\s*$/)
237
243
  @outputs[index][:state] = :err
238
- @outputs[index][:msg] = 'Write 4 spaces before %features, and no text after'
244
+ @outputs[index][:msg] = "Write 4 spaces before %features, and no text after"
239
245
  end
240
246
  end
241
247
 
@@ -262,7 +268,7 @@ class CheckHamlData
262
268
  end
263
269
 
264
270
  def count_spaces(line)
265
- a = line.split('%')
266
- a[0].count(' ')
271
+ a = line.split("%")
272
+ a[0].count(" ")
267
273
  end
268
274
  end