asker-tool 2.1.5 → 2.2.1

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -17
  3. data/bin/asker +2 -1
  4. data/lib/asker/ai/ai.rb +10 -3
  5. data/lib/asker/ai/ai_calculate.rb +20 -6
  6. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  7. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  8. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  9. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  10. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  11. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  12. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  13. data/lib/asker/ai/concept_ai.rb +13 -3
  14. data/lib/asker/ai/question.rb +28 -6
  15. data/lib/asker/ai/stages/base_stage.rb +45 -6
  16. data/lib/asker/ai/stages/stage_b.rb +100 -50
  17. data/lib/asker/ai/stages/stage_d.rb +75 -90
  18. data/lib/asker/ai/stages/stage_f.rb +64 -36
  19. data/lib/asker/ai/stages/stage_i.rb +79 -92
  20. data/lib/asker/ai/stages/stage_s.rb +41 -36
  21. data/lib/asker/ai/stages/stage_t.rb +149 -108
  22. data/lib/asker/application.rb +19 -11
  23. data/lib/asker/cli.rb +31 -44
  24. data/lib/asker/data/code.rb +62 -0
  25. data/lib/asker/data/column.rb +31 -21
  26. data/lib/asker/data/concept.rb +109 -65
  27. data/lib/asker/data/data_field.rb +14 -0
  28. data/lib/asker/data/project_data.rb +63 -0
  29. data/lib/asker/data/row.rb +75 -52
  30. data/lib/asker/data/table.rb +91 -42
  31. data/lib/asker/data/template.rb +3 -1
  32. data/lib/asker/data/world.rb +51 -35
  33. data/lib/asker/displayer/code_displayer.rb +7 -0
  34. data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
  35. data/lib/asker/displayer/concept_ai_displayer.rb +74 -53
  36. data/lib/asker/displayer/concept_displayer.rb +16 -9
  37. data/lib/asker/displayer/stats_displayer.rb +12 -3
  38. data/lib/asker/exporter/concept_ai_gift_exporter.rb +19 -11
  39. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
  40. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +13 -6
  41. data/lib/asker/exporter/concept_doc_exporter.rb +14 -1
  42. data/lib/asker/exporter/data_gift_exporter.rb +29 -0
  43. data/lib/asker/exporter/output_file_exporter.rb +9 -6
  44. data/lib/asker/files/{config.ini → asker.ini} +48 -1
  45. data/lib/asker/files/example-concept.haml +0 -1
  46. data/lib/asker/files/language/du/connectors.yaml +81 -0
  47. data/lib/asker/{lang/locales/fr → files/language/du}/mistakes.yaml +1 -1
  48. data/lib/asker/files/language/du/templates.yaml +29 -0
  49. data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
  50. data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
  51. data/lib/asker/files/language/en/templates.yaml +29 -0
  52. data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
  53. data/lib/asker/files/language/es/mistakes.yaml +84 -0
  54. data/lib/asker/files/language/es/templates.yaml +29 -0
  55. data/lib/asker/files/language/fr/connectors.yaml +76 -0
  56. data/lib/asker/{lang/locales/es → files/language/fr}/mistakes.yaml +0 -0
  57. data/lib/asker/files/language/fr/templates.yaml +29 -0
  58. data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
  59. data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
  60. data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
  61. data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
  62. data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
  63. data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
  64. data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
  65. data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
  66. data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
  67. data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
  68. data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
  69. data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
  70. data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
  71. data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
  72. data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
  73. data/lib/asker/formatter/concept_doc_formatter.rb +0 -4
  74. data/lib/asker/formatter/concept_string_formatter.rb +7 -4
  75. data/lib/asker/formatter/moodle/matching.erb +38 -0
  76. data/lib/asker/formatter/moodle/multichoice.erb +49 -0
  77. data/lib/asker/formatter/moodle/shortanswer.erb +30 -0
  78. data/lib/asker/formatter/moodle/truefalse.erb +47 -0
  79. data/lib/asker/formatter/question_gift_formatter.rb +30 -20
  80. data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
  81. data/lib/asker/{checker.rb → input_checker.rb} +126 -49
  82. data/lib/asker/lang/lang.rb +17 -10
  83. data/lib/asker/lang/lang_factory.rb +32 -5
  84. data/lib/asker/lang/text_actions.rb +87 -69
  85. data/lib/asker/loader/code_loader.rb +4 -4
  86. data/lib/asker/loader/content_loader.rb +21 -19
  87. data/lib/asker/loader/directory_loader.rb +1 -8
  88. data/lib/asker/loader/embedded_file.rb +42 -0
  89. data/lib/asker/loader/file_loader.rb +3 -14
  90. data/lib/asker/loader/haml_loader.rb +15 -0
  91. data/lib/asker/loader/image_url_loader.rb +8 -12
  92. data/lib/asker/loader/input_loader.rb +13 -15
  93. data/lib/asker/loader/project_loader.rb +25 -15
  94. data/lib/asker/logger.rb +36 -9
  95. data/lib/asker/skeleton.rb +23 -13
  96. data/lib/asker.rb +76 -42
  97. metadata +53 -54
  98. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  99. data/lib/asker/code/code.rb +0 -53
  100. data/lib/asker/lang/locales/du/templates.yaml +0 -50
  101. data/lib/asker/lang/locales/en/templates.yaml +0 -29
  102. data/lib/asker/lang/locales/es/templates.yaml +0 -29
  103. data/lib/asker/lang/locales/fr/connectors.yaml +0 -92
  104. data/lib/asker/lang/locales/fr/templates.yaml +0 -29
  105. data/lib/asker/project.rb +0 -172
@@ -1,170 +1,211 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
4
  require_relative 'base_stage'
5
5
  require_relative '../question'
6
6
 
7
+ ##
8
+ # StageT create questions based con Table data
9
+ # range t1-t9
10
+ # rubocop:disable Metrics/ClassLength
7
11
  class StageT < BaseStage
8
- #range t1-t9...c1-c9
9
-
10
- def run(pTable, pRow, pList) #process_tableXfields
12
+ # process_tableXfields
13
+ # rubocop:disable Metrics/MethodLength
14
+ # rubocop:disable Metrics/AbcSize
15
+ def run(table, row, list)
11
16
  questions = []
12
- return questions unless type=="text"
13
-
14
- if pTable.fields.count>1 then
15
- questions = questions + process_table2fields(pTable, pRow, pList, 0, 1)
16
- elsif pTable.fields.count>2 then
17
- questions = questions + process_table2fields(pTable, pRow, pList, 0, 2)
18
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 2)
19
- elsif pTable.fields.count>3 then
20
- questions = questions + process_table2fields(pTable, pRow, pList, 0, 3)
21
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 3)
22
- questions = questions + process_table2fields(pTable, pRow, pList, 2, 3)
17
+ return questions unless concept.type == 'text'
18
+
19
+ if table.fields.count == 2
20
+ questions += process_table2fields(table, row, list, 0, 1)
21
+ elsif table.fields.count == 3
22
+ questions += process_table2fields(table, row, list, 0, 1)
23
+ questions += process_table2fields(table, row, list, 0, 2)
24
+ elsif table.fields.count == 4
25
+ questions += process_table2fields(table, row, list, 0, 1)
26
+ questions += process_table2fields(table, row, list, 0, 2)
27
+ questions += process_table2fields(table, row, list, 0, 3)
23
28
  end
24
29
 
25
- return questions
30
+ questions
26
31
  end
32
+ # rubocop:enable Metrics/MethodLength
33
+ # rubocop:enable Metrics/AbcSize
34
+
35
+ private
27
36
 
28
- private
29
- def process_table2fields(lTable, lRow, pList, pCol1, pCol2)
37
+ # rubocop:disable Metrics/MethodLength
38
+ # rubocop:disable Metrics/AbcSize
39
+ # rubocop:disable Metrics/CyclomaticComplexity
40
+ # rubocop:disable Metrics/PerceivedComplexity
41
+ def process_table2fields(table, row, list, col1, col2)
30
42
  questions = []
31
- #create gift questions
32
-
33
- # Using the column #0
34
- s=Set.new [ lRow[:data][0] , lang.text_for(:none) ]
35
- pList.each { |i| s.add( i[:data][0] ) }
36
- a=s.to_a
37
-
38
- if s.count>3 then
39
- q=Question.new
40
- q.name="#{name}-#{num.to_s}-t1table-#{lTable.name}"
41
- q.text=lang.text_for(:t1table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
42
- q.good=lRow[:data][0]
43
+ lang = concept.lang
44
+ # create questions
45
+
46
+ # Question choice: Using the column #0
47
+ s = Set.new [row[:data][col1], lang.text_for(:none)]
48
+ list.each { |i| s.add(i[:data][col1]) }
49
+ a = s.to_a
50
+
51
+ if s.count > 3
52
+ q = Question.new
53
+ q.name = "#{name}-#{num}-t1table-#{table.name}"
54
+ q.text = random_image_for(name) \
55
+ + lang.text_for(:t1table, name, table.fields[col1].capitalize, \
56
+ table.fields[col2].capitalize, row[:data][col2])
57
+ q.good = row[:data][col1]
43
58
  q.bads << lang.text_for(:none)
44
59
  q.bads << a[2]
45
60
  q.bads << a[3]
46
61
  questions << q
47
62
  end
48
63
 
49
- s=Set.new [ lRow[:data][0], lang.text_for(:none) ]
50
- pList.each { |i| s.add( i[:data][0] ) }
51
- a=s.to_a
52
-
53
- if s.count>4 then
54
- q=Question.new
55
- q.name="#{name}-#{num.to_s}-t2table-#{lTable.name}"
56
- q.text=lang.text_for(:t2table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
57
- q.good=lang.text_for(:none)
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
67
+
68
+ if s.count > 4
69
+ q = Question.new
70
+ q.name = "#{name}-#{num}-t2table-#{table.name}"
71
+ q.text = random_image_for(name) \
72
+ + lang.text_for(:t2table, name, table.fields[col1].capitalize, \
73
+ table.fields[col2].capitalize, row[:data][col2])
74
+ q.good = lang.text_for(:none)
58
75
  q.bads << a[2]
59
76
  q.bads << a[3]
60
77
  q.bads << a[4]
61
78
  questions << q
62
79
  end
63
80
 
64
- # Using the column #1
65
- s=Set.new [ lRow[:data][1], lang.text_for(:none) ]
66
- pList.each { |i| s.add( i[:data][1] ) }
67
- a=s.to_a
68
-
69
- if s.count>3 then
70
- q=Question.new
71
- q.name="#{name}-#{num.to_s}-t3table-#{lTable.name}"
72
- q.text=lang.text_for(:t3table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
73
- q.good=a[0]
81
+ # Question choice: Using the column #1
82
+ s = Set.new [row[:data][col2], lang.text_for(:none)]
83
+ list.each { |i| s.add(i[:data][col2]) }
84
+ a = s.to_a
85
+
86
+ if s.count > 3
87
+ q = Question.new
88
+ q.name = "#{name}-#{num}-t3table-#{table.name}"
89
+ q.text = random_image_for(name) \
90
+ + lang.text_for(:t3table, name, table.fields[col1].capitalize, \
91
+ row[:data][col1], table.fields[col2].capitalize)
92
+ q.good = a[0]
74
93
  q.bads << lang.text_for(:none)
75
94
  q.bads << a[2]
76
95
  q.bads << a[3]
77
96
  questions << q
78
97
  end
79
98
 
80
- s=Set.new [ lRow[:data][1], lang.text_for(:none) ]
81
- pList.each { |i| s.add( i[:data][1] ) }
82
- a=s.to_a
83
-
84
- if s.count>4 then
85
- q=Question.new
86
- q.name="#{name}-#{num.to_s}-t4table-#{lTable.name}"
87
- q.text=lang.text_for(:t4table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
88
- q.good=lang.text_for(:none)
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
102
+
103
+ if s.count > 4
104
+ q = Question.new
105
+ q.name = "#{name}-#{num}-t4table-#{table.name}"
106
+ q.text = random_image_for(name) \
107
+ + lang.text_for(:t4table, name, table.fields[col1].capitalize, \
108
+ row[:data][col1], table.fields[col2].capitalize)
109
+ q.good = lang.text_for(:none)
89
110
  q.bads << a[2]
90
111
  q.bads << a[3]
91
112
  q.bads << a[4]
92
113
  questions << q
93
114
  end
94
115
 
95
- # Boolean association TRUE
96
- q=Question.new
116
+ # Question Boolean: TRUE
117
+ q = Question.new
97
118
  q.set_boolean
98
- q.name="#{name}-#{num.to_s}t5table-#{lTable.name}"
99
- q.text=lang.text_for(:t5table, name, lTable.fields[0].capitalize, lRow[:data][0] ,lTable.fields[1].capitalize, lRow[:data][1] )
100
- q.good="TRUE"
119
+ q.name = "#{name}-#{num}t5table-#{table.name}"
120
+ 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'
101
124
  questions << q
102
125
 
103
- # Boolean association FALSE
104
- s=Set.new [ lRow[:data][1] ]
105
- pList.each { |i| s.add( i[:data][1] ) }
106
- a=s.to_a
126
+ # Question Boolean: FALSE
127
+ s = Set.new [row[:data][col2]]
128
+ list.each { |i| s.add(i[:data][col2]) }
129
+ a = s.to_a
107
130
 
108
- if s.count>1 then
109
- q=Question.new
131
+ if s.count > 1
132
+ q = Question.new
110
133
  q.set_boolean
111
- q.name="#{name}-#{num.to_s}-t6table-#{lTable.name}"
112
- q.text=lang.text_for(:t6table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, a[1] )
113
- q.good="FALSE"
134
+ q.name = "#{name}-#{num}-t6table-#{table.name}"
135
+ 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'
114
139
  questions << q
115
140
  end
116
141
 
117
- s=Set.new [ lRow[:data][0] ]
118
- pList.each { |i| s.add( i[:data][0] ) }
119
- a=s.to_a
142
+ s = Set.new [row[:data][col1]]
143
+ list.each { |i| s.add(i[:data][col1]) }
144
+ a = s.to_a
120
145
 
121
- if s.count>1 then
122
- q=Question.new
146
+ if s.count > 1
147
+ q = Question.new
123
148
  q.set_boolean
124
- q.name="#{name}-#{num.to_s}t7table-#{lTable.name}"
125
- q.text=lang.text_for(:t7table, name, lTable.fields[0].capitalize, a[1], lTable.fields[1].capitalize, lRow[:data][1] )
126
- q.good="FALSE"
149
+ q.name = "#{name}-#{num}t7table-#{table.name}"
150
+ 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'
127
154
  questions << q
128
155
  end
129
156
 
130
- # Short answer with column #0, 1 word
131
- if lang.count_words(lRow[:data][0])==1 then
132
- q=Question.new
157
+ # Question Short: column #0, 1 word
158
+ if lang.count_words(row[:data][col1]) == 1
159
+ q = Question.new
133
160
  q.set_short
134
- q.name="#{name}-#{num.to_s}t8table-#{lTable.name}"
135
- q.text=lang.text_for(:t8table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize)
136
- q.shorts << lRow[:data][0]
137
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
161
+ q.name = "#{name}-#{num}t8table-#{table.name}"
162
+ q.text = random_image_for(name) \
163
+ + lang.text_for(:t8table, name, table.fields[col2].capitalize, \
164
+ row[:data][col2], table.fields[col1].capitalize)
165
+ q.shorts << row[:data][col1]
166
+ q.shorts << row[:data][col1].gsub('-', ' ').gsub('_', ' ')
138
167
  questions << q
139
- elsif lang.count_words(lRow[:data][0])==2 then
140
- q=Question.new
168
+ elsif lang.count_words(row[:data][col1]) == 2
169
+ q = Question.new
141
170
  q.set_short
142
- q.name="#{name}-#{num.to_s}t9table-#{lTable.name}"
143
- q.text=lang.text_for(:t9table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize, "[#{lang.hide_text(lRow[:data][0])}]", lang.count_words(lRow[:data][0]) )
144
- q.shorts << lRow[:data][0]
145
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
171
+ q.name = "#{name}-#{num}t9table-#{table.name}"
172
+ 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]))
176
+ q.shorts << row[:data][col1]
177
+ q.shorts << row[:data][col1].gsub('-', ' ').gsub('_', ' ')
146
178
  questions << q
147
179
  end
148
180
 
149
- # Short answer with column #1, 1 word
150
- if lang.count_words(lRow[:data][1])==1 then
151
- q=Question.new
181
+ # Question Short: column #1, 1 word
182
+ if lang.count_words(row[:data][col2]) == 1
183
+ q = Question.new
152
184
  q.set_short
153
- q.name="#{name}-#{num.to_s}t8table-#{lTable.name}"
154
- q.text=lang.text_for(:t8table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
155
- q.shorts << lRow[:data][1]
156
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
185
+ q.name = "#{name}-#{num}t8table-#{table.name}"
186
+ q.text = random_image_for(name) \
187
+ + lang.text_for(:t8table, name, table.fields[col1].capitalize, \
188
+ row[:data][col1], table.fields[col2].capitalize)
189
+ q.shorts << row[:data][col2]
190
+ q.shorts << row[:data][col2].gsub('-', ' ').gsub('_', ' ')
157
191
  questions << q
158
- elsif lang.count_words(lRow[:data][1])==2 then
159
- q=Question.new
192
+ elsif lang.count_words(row[:data][col2]) == 2
193
+ q = Question.new
160
194
  q.set_short
161
- q.name="#{name}-#{num.to_s}t9table-#{lTable.name}"
162
- q.text=lang.text_for(:t9table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, "[#{lang.hide_text(lRow[:data][1])}]", lang.count_words(lRow[:data][1]) )
163
- q.shorts << lRow[:data][1]
164
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
195
+ q.name = "#{name}-#{num}t9table-#{table.name}"
196
+ 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]))
200
+ q.shorts << row[:data][col2]
201
+ q.shorts << row[:data][col2].gsub('-', ' ').gsub('_', ' ')
165
202
  questions << q
166
203
  end
167
- return questions
204
+ questions
168
205
  end
169
-
206
+ # rubocop:enable Metrics/MethodLength
207
+ # rubocop:enable Metrics/AbcSize
208
+ # rubocop:enable Metrics/CyclomaticComplexity
209
+ # rubocop:enable Metrics/PerceivedComplexity
170
210
  end
211
+ # rubocop:enable Metrics/ClassLength
@@ -2,29 +2,37 @@
2
2
 
3
3
  require 'singleton'
4
4
  require 'inifile'
5
+ require 'rainbow'
5
6
 
6
7
  # Global parameters
7
8
  class Application
8
9
  include Singleton
9
10
 
10
- VERSION = '2.1.5' # Application version
11
- NAME = 'asker' # Application name
12
- GEM = 'asker-tool' # Gem name
11
+ VERSION = '2.2.1'
12
+ NAME = 'asker'
13
+ GEM = 'asker-tool'
14
+ CONFIGFILE = 'asker.ini'
13
15
  attr_reader :config
14
16
 
15
- ##
16
- # Initialize Application singleton
17
17
  def initialize
18
18
  reset
19
19
  end
20
20
 
21
- ##
22
- # Initialize config values from external "config.ini" file.
23
21
  def reset
24
- filename = File.join(Dir.pwd, 'config.ini')
25
- unless File.exist? filename
26
- filename = File.join(File.dirname(__FILE__), 'files', 'config.ini')
22
+ filename = File.join(Dir.pwd, CONFIGFILE)
23
+ filename = File.join(File.dirname(__FILE__), 'files', CONFIGFILE) unless File.exist? filename
24
+
25
+ begin
26
+ @config = IniFile.load(filename)
27
+ rescue StandardError => e
28
+ puts e.display
29
+ puts Rainbow('[ERROR] Revise configuration file:').red.bright
30
+ puts Rainbow(" #{filename}").red.bright
31
+ exit 1
27
32
  end
28
- @config = IniFile.load(filename)
33
+ stages = @config['questions']['stages'].split(',')
34
+ @config['questions']['stages'] = stages.map(&:to_sym)
35
+ Rainbow.enabled = false
36
+ Rainbow.enabled = true if @config['global']['color'].downcase == 'yes'
29
37
  end
30
38
  end
data/lib/asker/cli.rb CHANGED
@@ -8,66 +8,38 @@ require_relative '../asker'
8
8
  ##
9
9
  # Command Line User Interface
10
10
  class CLI < Thor
11
- map ['h', '-h', '--help'] => 'help'
11
+ map ['--help'] => 'help'
12
12
 
13
- map ['v', '-v', '--version'] => 'version'
13
+ map ['--version'] => 'version'
14
14
  desc 'version', 'Show the program version'
15
- ##
16
- # Show current version
17
15
  def version
18
- print Rainbow(Application::NAME).bright.blue
19
- puts " (version #{Rainbow(Application::VERSION).green})"
16
+ puts "#{Application::NAME} version #{Application::VERSION}"
20
17
  end
21
18
 
22
19
  map ['f', '-f', '--file'] => 'file'
23
- desc 'file NAME', 'Build output files, from HAML/XML input file.'
24
- option :color, type: :boolean
20
+ desc '[file] FILEPATH', 'Build output files, from HAML/XML input file.'
25
21
  long_desc <<-LONGDESC
26
- Create output files, from input file (HAML/XML format).
27
22
 
28
23
  Build questions about contents defined into input file specified.
29
24
 
30
- Examples:
25
+ Create output files, from input file (HAML/XML format).
31
26
 
32
- (1) #{Rainbow('asker input/foo/foo.haml').yellow}, Build questions from HAML file.
27
+ Examples:
33
28
 
34
- (2) #{Rainbow('asker input/foo/foo.xml').yellow}, Build questions from XML file.
29
+ (1) #{Rainbow('asker input/foo/foo.haml').aqua}, Build questions from HAML file.
35
30
 
36
- (3) #{Rainbow('asker file --no-color input/foo/foo.haml').yellow}, Same as (1) but without colors.
31
+ (2) #{Rainbow('asker input/foo/foo.xml').aqua}, Build questions from XML file.
37
32
 
38
- (4) #{Rainbow('asker projects/foo/foo.yaml').yellow}, Build questions from YAML project file.
33
+ (3) #{Rainbow('asker projects/foo/foo.yaml').aqua}, Build questions from YAML project file.
39
34
 
40
35
  LONGDESC
41
- ##
42
- # Create questions from input file
43
- # @param filename (String) Path to input file
44
36
  def file(filename)
45
- # Enable/disable color output
46
- Rainbow.enabled = false if options['color'] == false
47
37
  # Asker start processing input file
48
38
  Asker.start(filename)
49
39
  end
50
40
 
51
- map ['i', '-i', '--init'] => 'init'
52
- desc 'init', 'Create default INI config fie'
53
- ##
54
- # Create default INI config file
55
- def init
56
- src = File.join(File.dirname(__FILE__), 'files', 'config.ini')
57
- dst = File.join(Dir.pwd, 'config.ini')
58
- if File.exist? dst
59
- puts "[WARN] Exists file! => #{Rainbow(File.basename(dst)).yellow.bright}"
60
- else
61
- FileUtils.cp(src, dst)
62
- puts "[ OK ] Create file => #{Rainbow(File.basename(dst)).green}"
63
- end
64
- end
65
-
66
- map ['c', '-c', '--check'] => 'check'
67
- desc 'check', 'Check input HAML file syntax'
68
- ##
69
- # Check input file syntax
70
- # @param filename (String) Path to input file
41
+ map ['--check'] => 'check'
42
+ desc 'check FILEPATH', 'Check input HAML file syntax'
71
43
  def check(filename)
72
44
  # Enable/disable color output
73
45
  Rainbow.enabled = false if options['color'] == false
@@ -75,14 +47,19 @@ class CLI < Thor
75
47
  Asker.check(filename)
76
48
  end
77
49
 
78
- map ['n', '-b', '--new', 'new'] => 'create_skeleton'
79
- desc 'new', 'Create Asker demo input files'
50
+ map ['--init'] => 'init'
51
+ desc 'init', 'Create default INI config file'
52
+ def init
53
+ Asker.init
54
+ end
55
+
56
+ map ['new','--new'] => 'new_input'
57
+ desc 'new DIRPATH', 'Create Asker demo input files'
80
58
  ##
81
59
  # Create Asker demo input files
82
60
  # @param dirname (String) Path to folder
83
- def create_skeleton(dirname)
84
- # Asker start processing input file
85
- Asker.create_skeleton(dirname)
61
+ def new_input(dirname)
62
+ Asker.new_input(dirname)
86
63
  end
87
64
 
88
65
  ##
@@ -92,4 +69,14 @@ class CLI < Thor
92
69
  def method_missing(method, *_args, &_block)
93
70
  file(method.to_s)
94
71
  end
72
+
73
+ def respond_to_missing?(_method_name)
74
+ true
75
+ end
76
+
77
+ ##
78
+ # Thor stop and show messages on screen on failure
79
+ def self.exit_on_failure?
80
+ true
81
+ end
95
82
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../ai/code/code_ai_factory'
4
+
5
+ class Code
6
+ attr_reader :dirname, :filename, :type
7
+ attr_accessor :process, :features
8
+ attr_reader :lines, :questions
9
+
10
+ def initialize(dirname, filename, type)
11
+ @dirname = dirname
12
+ @filename = filename
13
+ @type = type
14
+ @filepath = File.join(@dirname, @filename)
15
+ @process = false
16
+ @features = []
17
+ @lines = load(@filepath)
18
+ @questions = []
19
+ end
20
+
21
+ def process?
22
+ @process
23
+ end
24
+
25
+ def lines_to_s(lines)
26
+ out = ''
27
+ lines.each_with_index do |line, index|
28
+ out << format("%2d| #{line}\n", (index + 1))
29
+ end
30
+ out
31
+ end
32
+
33
+ private
34
+
35
+ def load(filepath)
36
+ return if filepath.nil?
37
+
38
+ unless File.exist? filepath
39
+ puts Rainbow("[ERROR] Unkown file #{filepath}").red.bright
40
+ return
41
+ end
42
+ content = File.read(filepath)
43
+ encode_and_split(content)
44
+ end
45
+
46
+ def encode_and_split(text, encoding = :default)
47
+ # Convert text to UTF-8 deleting unknown chars
48
+ text ||= '' # Ensure text is not nil
49
+ flag = [:default, 'UTF-8'].include? encoding
50
+ return text.encode('UTF-8', invalid: :replace).split("\n") if flag
51
+
52
+ # Convert text from input ENCODING to UTF-8
53
+ ec = Encoding::Converter.new(encoding.to_s, 'UTF-8')
54
+ begin
55
+ text = ec.convert(text)
56
+ rescue StandardError => e
57
+ puts "[ERROR] Encoding: #{e}"
58
+ end
59
+
60
+ text.split("\n")
61
+ end
62
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # encoding: utf-8
3
2
 
4
3
  # Contain data information for every column
5
4
  # Params:
@@ -9,10 +8,15 @@
9
8
  class Column
10
9
  attr_reader :row, :index, :id, :raw, :lang, :type, :simple
11
10
 
11
+ ##
12
+ # initialize Column
13
+ # @param row (Row)
14
+ # @param index (Integer)
15
+ # @param xml_data (XMLdata)
12
16
  def initialize(row, index, xml_data)
13
17
  @row = row
14
18
  @index = index
15
- @id = @row.id + '.' + @index.to_s
19
+ @id = "#{@row.id}.#{@index}"
16
20
  @raw = ''
17
21
  @lang = @row.langs[@index]
18
22
  @type = @row.types[@index]
@@ -28,35 +32,41 @@ class Column
28
32
  return "<img src=\"#{raw}\" alt\=\"image\">"
29
33
  when 'textfile_path'
30
34
  return "<pre>#{raw}</pre>"
31
- else
32
- return "ERROR type #{@type}"
33
35
  end
36
+ "ERROR type #{@type}"
34
37
  end
35
38
 
36
39
  private
37
40
 
38
41
  def read_data_from_xml(xml_data)
39
- raise '[ERROR] Column XML data with elements!' if xml_data.elements.count.positive?
42
+ raise '[ERROR] Column with elements!' if xml_data.elements.count.positive?
40
43
 
41
44
  @raw = xml_data.text.strip.to_s
42
45
 
43
46
  # read attributes from XML input data
44
- if xml_data.attributes['lang']
45
- code = xml_data.attributes['lang'].strip
46
- if code != @lang.code
47
- @lang = LangFactory.instance.get(code)
48
- @simple[:lang] = false
49
- @row.simple_off(:lang)
50
- end
51
- end
47
+ read_lang_from_xml(xml_data)
48
+ read_type_from_xml(xml_data)
49
+ end
52
50
 
53
- if xml_data.attributes['type']
54
- type = xml_data.attributes['type'].strip
55
- if type != @type.to_s
56
- @type = type
57
- @simple[:type] = false
58
- @row.simple_off(:type)
59
- end
60
- end
51
+ def read_lang_from_xml(xml_data)
52
+ return unless xml_data.attributes['lang']
53
+
54
+ code = xml_data.attributes['lang'].strip
55
+ return if code == @lang.code
56
+
57
+ @lang = LangFactory.instance.get(code)
58
+ @simple[:lang] = false
59
+ @row.simple_off(:lang)
60
+ end
61
+
62
+ def read_type_from_xml(xml_data)
63
+ return unless xml_data.attributes['type']
64
+
65
+ type = xml_data.attributes['type'].strip
66
+ return if type == @type.to_s
67
+
68
+ @type = type
69
+ @simple[:type] = false
70
+ @row.simple_off(:type)
61
71
  end
62
72
  end