asker-tool 2.5.9 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -7
- data/lib/asker/ai/ai.rb +17 -22
- data/lib/asker/ai/ai_calculate.rb +10 -17
- data/lib/asker/ai/code/base_code_ai.rb +5 -30
- data/lib/asker/ai/code/code_ai_factory.rb +6 -12
- data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
- data/lib/asker/ai/code/python_code_ai.rb +35 -36
- data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
- data/lib/asker/ai/code/sql_code_ai.rb +20 -21
- data/lib/asker/ai/concept_ai.rb +12 -22
- data/lib/asker/ai/problem/problem_ai.rb +226 -0
- data/lib/asker/ai/question.rb +34 -45
- data/lib/asker/ai/stages/base_stage.rb +7 -7
- data/lib/asker/ai/stages/main.rb +6 -7
- data/lib/asker/ai/stages/stage_b.rb +62 -28
- data/lib/asker/ai/stages/stage_d.rb +10 -10
- data/lib/asker/ai/stages/stage_f.rb +17 -17
- data/lib/asker/ai/stages/stage_i.rb +8 -18
- data/lib/asker/ai/stages/stage_s.rb +28 -26
- data/lib/asker/ai/stages/stage_t.rb +54 -76
- data/lib/asker/application.rb +15 -14
- data/lib/asker/check_input/check_haml_data.rb +57 -51
- data/lib/asker/check_input/check_table.rb +26 -19
- data/lib/asker/check_input.rb +10 -22
- data/lib/asker/cli.rb +43 -24
- data/lib/asker/data/code.rb +10 -9
- data/lib/asker/data/column.rb +21 -17
- data/lib/asker/data/concept.rb +24 -37
- data/lib/asker/data/data_field.rb +2 -2
- data/lib/asker/data/problem.rb +112 -0
- data/lib/asker/data/project_data.rb +11 -15
- data/lib/asker/data/row.rb +25 -23
- data/lib/asker/data/table.rb +25 -46
- data/lib/asker/data/template.rb +7 -7
- data/lib/asker/data/world.rb +3 -3
- data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
- data/lib/asker/displayer/code_displayer.rb +10 -10
- data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
- data/lib/asker/displayer/concept_ai_displayer.rb +22 -34
- data/lib/asker/displayer/concept_displayer.rb +9 -11
- data/lib/asker/displayer/problem_displayer.rb +45 -0
- data/lib/asker/displayer/stats_displayer.rb +7 -12
- data/lib/asker/exporter/code_gift_exporter.rb +2 -2
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
- data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
- data/lib/asker/exporter/data_gift_exporter.rb +14 -15
- data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
- data/lib/asker/exporter/output_file_exporter.rb +9 -8
- data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
- data/lib/asker/files/language/ca/templates.yaml +6 -0
- data/lib/asker/files/language/du/templates.yaml +6 -0
- data/lib/asker/files/language/en/templates.yaml +7 -1
- data/lib/asker/files/language/es/templates.yaml +6 -0
- data/lib/asker/files/language/fr/templates.yaml +6 -0
- data/lib/asker/formatter/code_string_formatter.rb +5 -5
- data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
- data/lib/asker/formatter/concept_string_formatter.rb +27 -24
- data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
- data/lib/asker/formatter/moodle/gapfill.erb +57 -0
- data/lib/asker/formatter/moodle/ordering.erb +41 -0
- data/lib/asker/formatter/question_gift_formatter.rb +41 -14
- data/lib/asker/formatter/question_hash_formatter.rb +5 -6
- data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
- data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
- data/lib/asker/lang/lang.rb +16 -16
- data/lib/asker/lang/lang_factory.rb +13 -16
- data/lib/asker/lang/text_actions.rb +20 -18
- data/lib/asker/loader/code_loader.rb +10 -22
- data/lib/asker/loader/content_loader.rb +42 -49
- data/lib/asker/loader/directory_loader.rb +13 -16
- data/lib/asker/loader/embedded_file.rb +29 -24
- data/lib/asker/loader/file_loader.rb +7 -6
- data/lib/asker/loader/haml_loader.rb +6 -5
- data/lib/asker/loader/image_url_loader.rb +21 -18
- data/lib/asker/loader/input_loader.rb +27 -14
- data/lib/asker/loader/problem_loader.rb +88 -0
- data/lib/asker/loader/project_loader.rb +11 -28
- data/lib/asker/logger.rb +22 -13
- data/lib/asker/skeleton.rb +27 -43
- data/lib/asker/start.rb +44 -0
- data/lib/asker/version.rb +1 -1
- data/lib/asker.rb +7 -53
- metadata +12 -20
- data/lib/asker/ai/code/problem_code_ai.rb +0 -176
- data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "rainbow"
|
4
|
+
require "terminal-table"
|
5
5
|
|
6
6
|
# Define methods to transform Concept into String
|
7
7
|
module ConceptStringFormatter
|
@@ -15,32 +15,33 @@ module ConceptStringFormatter
|
|
15
15
|
tt.to_s
|
16
16
|
end
|
17
17
|
|
18
|
-
# rubocop:disable Metrics/AbcSize
|
19
|
-
# rubocop:disable Metrics/MethodLength
|
20
18
|
private_class_method def self.get_tt_rows(concept)
|
21
19
|
rows = []
|
22
20
|
rows << [Rainbow(concept.id.to_s).bright,
|
23
|
-
|
24
|
-
|
25
|
-
rows << [Rainbow(
|
26
|
-
rows << [Rainbow(
|
27
|
-
rows << [Rainbow(
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
Rainbow(concept.name(:screen)).green.bright]
|
22
|
+
# + " (lang=#{concept.lang.lang}) "]
|
23
|
+
# rows << [Rainbow("Filename").white, concept.filename]
|
24
|
+
# rows << [Rainbow("Context").white, concept.context.join(', ').to_s]
|
25
|
+
rows << [Rainbow("Tags").white, concept.tags.join(", ").to_s]
|
26
|
+
unless concept.reference_to.size.zero?
|
27
|
+
rows << [Rainbow("Reference to").white,
|
28
|
+
concept.reference_to.join(", ")[0...70].to_s]
|
29
|
+
end
|
30
|
+
unless concept.referenced_by.size.zero?
|
31
|
+
rows << [Rainbow("Referenced by").white,
|
32
|
+
concept.referenced_by.join(", ")[0...70].to_s]
|
33
|
+
end
|
32
34
|
rows << format_texts(concept)
|
33
35
|
unless concept.images.size.zero?
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
counter = concept.images.size
|
37
|
+
# counter1 = 0
|
38
|
+
# concept.images.each { |image| counter1 += 1 if image[:file] == :none }
|
39
|
+
# counter2 = concept.images.size - counter1
|
40
|
+
rows << [Rainbow("def(file)").white, "#{counter} file/s"]
|
38
41
|
end
|
39
42
|
rows << format_tables(concept) unless concept.tables.count.zero?
|
40
43
|
rows << format_neighbors(concept)
|
41
44
|
end
|
42
|
-
# rubocop:enable Metrics/AbcSize
|
43
|
-
# rubocop:enable Metrics/MethodLength
|
44
45
|
|
45
46
|
private_class_method def self.format_texts(concept)
|
46
47
|
list = []
|
@@ -49,22 +50,24 @@ module ConceptStringFormatter
|
|
49
50
|
list << i.to_s
|
50
51
|
next
|
51
52
|
end
|
52
|
-
list << i[0...70].to_s +
|
53
|
+
list << i[0...70].to_s + "..."
|
53
54
|
end
|
54
|
-
[Rainbow(
|
55
|
+
# [Rainbow("def").white, list.join("\n")]
|
56
|
+
[Rainbow("def").white, list.size.to_s]
|
55
57
|
end
|
56
58
|
|
57
59
|
private_class_method def self.format_tables(concept)
|
58
60
|
return [] if concept.tables.count.zero?
|
59
61
|
|
60
62
|
list = concept.tables.map(&:to_s)
|
61
|
-
[Rainbow(
|
63
|
+
[Rainbow("tables").white, list.join("\n")]
|
62
64
|
end
|
63
65
|
|
64
66
|
private_class_method def self.format_neighbors(concept)
|
65
67
|
list = concept.neighbors[0..4].map do |i|
|
66
|
-
|
68
|
+
value = Rainbow(i[:value].to_s[0..4]).white
|
69
|
+
"#{value} #{i[:concept].name(:screen)}"
|
67
70
|
end
|
68
|
-
[Rainbow(
|
71
|
+
[Rainbow("neighbors").white, list.join("\n")]
|
69
72
|
end
|
70
73
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<% unless question.comment.nil? || question.comment.empty? %>
|
2
|
+
<!-- question: <%= question.comment %> -->
|
3
|
+
<% end %>
|
4
|
+
<question type="ddmatch">
|
5
|
+
<name>
|
6
|
+
<text><%= question.name %></text>
|
7
|
+
</name>
|
8
|
+
<questiontext format="html">
|
9
|
+
<text><![CDATA[<%= question.text %>]]></text>
|
10
|
+
<% unless question.encode == :none %>
|
11
|
+
<%= question.encode %>
|
12
|
+
<% end %>
|
13
|
+
</questiontext>
|
14
|
+
<generalfeedback format="html">
|
15
|
+
<text></text>
|
16
|
+
</generalfeedback>
|
17
|
+
<defaultgrade>1.0000000</defaultgrade>
|
18
|
+
<penalty>0.3333333</penalty>
|
19
|
+
<hidden>0</hidden>
|
20
|
+
<idnumber></idnumber>
|
21
|
+
<shuffleanswers>true</shuffleanswers>
|
22
|
+
<correctfeedback format="html">
|
23
|
+
<text></text>
|
24
|
+
</correctfeedback>
|
25
|
+
<partiallycorrectfeedback format="html">
|
26
|
+
<text></text>
|
27
|
+
</partiallycorrectfeedback>
|
28
|
+
<incorrectfeedback format="html">
|
29
|
+
<text></text>
|
30
|
+
</incorrectfeedback>
|
31
|
+
<shownumcorrect/>
|
32
|
+
<% question.matching.each do |i, j| %>
|
33
|
+
<subquestion format="html">
|
34
|
+
<text><![CDATA[<%= i %>]]></text>
|
35
|
+
<answer format="html">
|
36
|
+
<text><![CDATA[<%= j %>]]></text>
|
37
|
+
</answer>
|
38
|
+
</subquestion>
|
39
|
+
<% end %>
|
40
|
+
</question>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<% unless question.comment.nil? || question.comment.empty? %>
|
2
|
+
<!-- question: <%= question.comment %> -->
|
3
|
+
<% end %>
|
4
|
+
<question type="gapfill">
|
5
|
+
<name>
|
6
|
+
<text><%= question.name %></text>
|
7
|
+
</name>
|
8
|
+
<questiontext format="html">
|
9
|
+
<text><![CDATA[<%= question.text %>]]></text>
|
10
|
+
<% unless question.encode == :none %>
|
11
|
+
<%= question.encode %>
|
12
|
+
<% end %>
|
13
|
+
</questiontext>
|
14
|
+
<generalfeedback format="html">
|
15
|
+
<text></text>
|
16
|
+
</generalfeedback>
|
17
|
+
<defaultgrade>2.0000000</defaultgrade>
|
18
|
+
<penalty>0.3333333</penalty>
|
19
|
+
<hidden>0</hidden>
|
20
|
+
<idnumber></idnumber>
|
21
|
+
<answerdisplay>dragdrop</answerdisplay>
|
22
|
+
<delimitchars>[]</delimitchars>
|
23
|
+
<casesensitive>0</casesensitive>
|
24
|
+
<noduplicates>0</noduplicates>
|
25
|
+
<disableregex>0</disableregex>
|
26
|
+
<fixedgapsize>0</fixedgapsize>
|
27
|
+
<optionsaftertext>0</optionsaftertext>
|
28
|
+
<letterhints>0</letterhints>
|
29
|
+
<singleuse>0</singleuse>
|
30
|
+
<% question.shorts.uniq! %>
|
31
|
+
<% question.shorts.each do |i| %>
|
32
|
+
<answer fraction="100" format="moodle_auto_format">
|
33
|
+
<text><![CDATA[<%= i %>]]></text>
|
34
|
+
<feedback format="html">
|
35
|
+
<text></text>
|
36
|
+
</feedback>
|
37
|
+
</answer>
|
38
|
+
<% end %>
|
39
|
+
<delimitchars>[]</delimitchars>
|
40
|
+
<answerdisplay>dragdrop</answerdisplay>
|
41
|
+
<casesensitive>0</casesensitive>
|
42
|
+
<noduplicates>0</noduplicates>
|
43
|
+
<disableregex>0</disableregex>
|
44
|
+
<fixedgapsize>0</fixedgapsize>
|
45
|
+
<optionsaftertext>0</optionsaftertext>
|
46
|
+
<letterhints>0</letterhints>
|
47
|
+
<!-- Gapfill release:2.133 version:2022032500 Moodle version:2020061514.02 release:3.9.14+ (Build: 20220603) -->
|
48
|
+
<correctfeedback format="html">
|
49
|
+
<text></text>
|
50
|
+
</correctfeedback>
|
51
|
+
<partiallycorrectfeedback format="html">
|
52
|
+
<text></text>
|
53
|
+
</partiallycorrectfeedback>
|
54
|
+
<incorrectfeedback format="html">
|
55
|
+
<text></text>
|
56
|
+
</incorrectfeedback>
|
57
|
+
</question>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<% unless question.comment.nil? || question.comment.empty? %>
|
2
|
+
<!-- question: <%= question.comment %> -->
|
3
|
+
<% end %>
|
4
|
+
<question type="ordering">
|
5
|
+
<name>
|
6
|
+
<text><%= question.name %></text>
|
7
|
+
</name>
|
8
|
+
<questiontext format="html">
|
9
|
+
<text><![CDATA[<%= question.text %>]]></text>
|
10
|
+
<% unless question.encode == :none %>
|
11
|
+
<%= question.encode %>
|
12
|
+
<% end %>
|
13
|
+
</questiontext>
|
14
|
+
<generalfeedback format="html">
|
15
|
+
<text><![CDATA[<%= question.feedback.to_s %>]]></text>
|
16
|
+
</generalfeedback>
|
17
|
+
<defaultgrade>1.0000000</defaultgrade>
|
18
|
+
<penalty>0.3333333</penalty>
|
19
|
+
<hidden>0</hidden>
|
20
|
+
<idnumber></idnumber>
|
21
|
+
<layouttype>VERTICAL</layouttype>
|
22
|
+
<selecttype>ALL</selecttype>
|
23
|
+
<selectcount>0</selectcount>
|
24
|
+
<gradingtype>ABSOLUTE_POSITION</gradingtype>
|
25
|
+
<showgrading>SHOW</showgrading>
|
26
|
+
<numberingstyle>none</numberingstyle>
|
27
|
+
<correctfeedback format="html">
|
28
|
+
<text>Respuesta correcta</text>
|
29
|
+
</correctfeedback>
|
30
|
+
<partiallycorrectfeedback format="html">
|
31
|
+
<text>Respuesta parcialmente correcta.</text>
|
32
|
+
</partiallycorrectfeedback>
|
33
|
+
<incorrectfeedback format="html">
|
34
|
+
<text>Respuesta incorrecta.</text>
|
35
|
+
</incorrectfeedback>
|
36
|
+
<% question.ordering.each_with_index do |step, index| %>
|
37
|
+
<answer fraction="<%= index + 1 %>" format="moodle_auto_format">
|
38
|
+
<text><%= step %></text>
|
39
|
+
</answer>
|
40
|
+
<% end %>
|
41
|
+
</question>
|
@@ -7,7 +7,7 @@ module QuestionGiftFormatter
|
|
7
7
|
# @param question (Question)
|
8
8
|
# @return String
|
9
9
|
def self.to_s(question)
|
10
|
-
s =
|
10
|
+
s = ""
|
11
11
|
return s unless question.encode == :none
|
12
12
|
|
13
13
|
# Return question using gift format
|
@@ -16,40 +16,48 @@ module QuestionGiftFormatter
|
|
16
16
|
s << "::#{question.name}::[html]#{sanitize(question.text)}\n"
|
17
17
|
|
18
18
|
case question.type
|
19
|
+
when :boolean
|
20
|
+
s << "{#{question.good}#####{sanitize(question.feedback.to_s)}}\n\n"
|
19
21
|
when :choice
|
20
22
|
s += "{\n"
|
21
23
|
a = [" =#{sanitize(question.good)}\n"]
|
22
|
-
penalties = [
|
24
|
+
penalties = ["", "%-50%", "%-33.33333%", "%-25%", "%-20%"]
|
23
25
|
penalty = penalties[question.bads.size]
|
24
26
|
|
25
27
|
question.bads.each { |i| a << (" ~#{penalty}" + sanitize(i) + "\n") }
|
26
28
|
a.shuffle! if question.shuffle?
|
27
29
|
a.each do |i|
|
28
30
|
text = i
|
29
|
-
text = i[0, 220] +
|
31
|
+
text = i[0, 220] + "...(ERROR: text too long)" if text.size > 255
|
30
32
|
s << text
|
31
33
|
end
|
32
34
|
s += " #####{sanitize(question.feedback.to_s)}\n" if question.feedback
|
33
35
|
s += "}\n\n"
|
34
|
-
when :
|
35
|
-
s << "
|
36
|
+
when :ddmatch
|
37
|
+
s << "// WARNING: can't export ddmatch questions to this format"
|
38
|
+
when :gapfill
|
39
|
+
s << "// WARNING: can't export gapfill questions to this format"
|
36
40
|
when :match
|
37
41
|
s << "{\n"
|
38
42
|
a = []
|
39
43
|
question.matching.each do |i, j|
|
40
|
-
i = i[0, 220] +
|
41
|
-
j = j[0, 220] +
|
44
|
+
i = i[0, 220] + "...(ERROR: text too long)" if i.size > 255
|
45
|
+
j = j[0, 220] + "...(ERROR: text too long)" if j.size > 255
|
42
46
|
a << " =#{sanitize(i)} -> #{sanitize(j)}\n"
|
43
47
|
end
|
44
48
|
a.shuffle! if question.shuffle?
|
45
49
|
a.each { |i| s << i }
|
46
50
|
s << "}\n\n"
|
51
|
+
when :ordering
|
52
|
+
s << "{>0 ALL VERTICAL ABSOLUTE_POSITION SHOW none\n"
|
53
|
+
question.ordering.each { |i| s << "#{i}\n" }
|
54
|
+
s << "}\n\n"
|
47
55
|
when :short
|
48
56
|
s << "{\n"
|
49
57
|
question.shorts.uniq!
|
50
58
|
question.shorts.each do |i|
|
51
59
|
text = i
|
52
|
-
text = i[0, 220] +
|
60
|
+
text = i[0, 220] + "...(ERROR: too long)" if text.size > 255
|
53
61
|
s << " =%100%#{text}#\n"
|
54
62
|
end
|
55
63
|
s << " #####{sanitize(question.feedback.to_s)}\n" if question.feedback
|
@@ -62,14 +70,33 @@ module QuestionGiftFormatter
|
|
62
70
|
# Sanitize gift text
|
63
71
|
# @param input (String)
|
64
72
|
# @return String
|
65
|
-
def self.sanitize(input =
|
73
|
+
def self.sanitize(input = "")
|
74
|
+
return sanitize_exclude_pre(input) if input.include? '<pre>'
|
75
|
+
|
66
76
|
output = input.dup
|
67
|
-
output.gsub!(
|
77
|
+
output.gsub!("#", '\#')
|
68
78
|
output.gsub!("\n", " ")
|
69
|
-
output.gsub!(
|
70
|
-
output.gsub!(
|
71
|
-
output.gsub!("
|
72
|
-
output.gsub!("
|
79
|
+
output.gsub!(":", '\:')
|
80
|
+
output.gsub!("=", '\=')
|
81
|
+
output.gsub!("{", "\\{")
|
82
|
+
output.gsub!("}", "\\}")
|
83
|
+
|
73
84
|
output
|
74
85
|
end
|
86
|
+
|
87
|
+
def self.sanitize_exclude_pre(input = "")
|
88
|
+
pres = input.split('<pre>')
|
89
|
+
|
90
|
+
pres = [pres[0]] + pres[1].split("</pre>")
|
91
|
+
[0, 2].each do |index|
|
92
|
+
pres[index].gsub!("#", '\#')
|
93
|
+
pres[index].gsub!("\n", " ")
|
94
|
+
pres[index].gsub!(":", '\:')
|
95
|
+
pres[index].gsub!("=", '\=')
|
96
|
+
pres[index].gsub!("{", "\\{")
|
97
|
+
pres[index].gsub!("}", "\\}")
|
98
|
+
end
|
99
|
+
|
100
|
+
pres.join("")
|
101
|
+
end
|
75
102
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# Transform Questions into YAML format
|
3
2
|
module QuestionHashFormatter
|
4
3
|
def self.to_hash(question)
|
@@ -26,14 +25,14 @@ module QuestionHashFormatter
|
|
26
25
|
s
|
27
26
|
end
|
28
27
|
|
29
|
-
def self.sanitize(input =
|
28
|
+
def self.sanitize(input = "")
|
30
29
|
output = input.dup
|
31
30
|
output.gsub!("#", "\\#")
|
32
|
-
output.
|
33
|
-
#output.gsub!(":", "\\:")
|
31
|
+
output.tr!("\n", " ")
|
32
|
+
# output.gsub!(":", "\\:")
|
34
33
|
output.gsub!("=", "\\=")
|
35
|
-
output.gsub!("
|
36
|
-
output.gsub!("
|
34
|
+
output.gsub!("{", "\\{")
|
35
|
+
output.gsub!("}", "\\}")
|
37
36
|
output
|
38
37
|
end
|
39
38
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
|
3
|
-
require
|
4
|
-
require_relative
|
3
|
+
require "erb"
|
4
|
+
require_relative "../application"
|
5
5
|
|
6
6
|
# Transform Questions into Gift format
|
7
7
|
class QuestionMoodleFormatter
|
@@ -12,20 +12,27 @@ class QuestionMoodleFormatter
|
|
12
12
|
def self.to_s(question)
|
13
13
|
case question.type
|
14
14
|
when :choice
|
15
|
-
fractions = Application.instance.config[
|
15
|
+
fractions = Application.instance.config["questions"]["fractions"]
|
16
16
|
penalties = fractions
|
17
17
|
# penalties = ['', '-50', '-33.33333', '-25', '-20']
|
18
18
|
# puts "[DEBUG] fractions : #{fractions}"
|
19
19
|
# puts "[DEBUG] penalties : #{penalties}"
|
20
20
|
|
21
21
|
penalty = penalties[question.bads.size]
|
22
|
-
template = File.read(File.join(File.dirname(__FILE__),
|
22
|
+
template = File.read(File.join(File.dirname(__FILE__), "moodle", "multichoice.erb"))
|
23
23
|
when :boolean
|
24
|
-
template = File.read(File.join(File.dirname(__FILE__),
|
24
|
+
template = File.read(File.join(File.dirname(__FILE__), "moodle", "truefalse.erb"))
|
25
|
+
when :ddmatch
|
26
|
+
template = File.read(File.join(File.dirname(__FILE__), "moodle", "ddmatch.erb"))
|
25
27
|
when :match
|
26
|
-
template = File.read(File.join(File.dirname(__FILE__),
|
28
|
+
template = File.read(File.join(File.dirname(__FILE__), "moodle", "matching.erb"))
|
29
|
+
when :ordering
|
30
|
+
template = File.read(File.join(File.dirname(__FILE__), "moodle", "ordering.erb"))
|
27
31
|
when :short
|
28
|
-
template = File.read(File.join(File.dirname(__FILE__),
|
32
|
+
template = File.read(File.join(File.dirname(__FILE__), "moodle", "shortanswer.erb"))
|
33
|
+
else
|
34
|
+
warn "[ERROR] QuestionMoodleFormatter: Unkown type (#{question.type})"
|
35
|
+
exit 1
|
29
36
|
end
|
30
37
|
renderer = ERB.new(template)
|
31
38
|
renderer.result(binding)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# UNDER DEVELOPMENT!!
|
2
2
|
|
3
|
+
require_relative "../logger"
|
4
|
+
|
3
5
|
module Rb2HamlExporter
|
4
6
|
def self.export(filename)
|
5
7
|
check_file filename
|
@@ -8,19 +10,18 @@ module Rb2HamlExporter
|
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.check_file(filename)
|
11
|
-
unless File.extname(filename).casecmp(
|
12
|
-
|
13
|
-
|
13
|
+
unless File.extname(filename).casecmp(".rb").zero?
|
14
|
+
Logger.error "Rb2HamlExporter: File name error #{filename}"
|
15
|
+
exit 1
|
14
16
|
end
|
15
17
|
unless File.exist? filename
|
16
|
-
|
17
|
-
|
18
|
+
Logger.error "Rb2HamlExporter: File #{filename} not found!"
|
19
|
+
exit 1
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
23
|
class Map
|
22
24
|
end
|
23
|
-
|
24
25
|
end
|
25
26
|
|
26
|
-
Rb2HamlExporter.export(
|
27
|
+
Rb2HamlExporter.export("docs/examples/home/rb/furniture.rb")
|
data/lib/asker/lang/lang.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
|
4
|
-
require_relative
|
5
|
-
require_relative '../logger'
|
1
|
+
require "erb"
|
2
|
+
require "yaml"
|
3
|
+
require_relative "text_actions"
|
4
|
+
require_relative "../logger"
|
6
5
|
|
7
6
|
class Lang
|
8
7
|
include TextActions
|
9
8
|
|
10
|
-
attr_reader :code
|
9
|
+
attr_reader :code
|
10
|
+
attr_reader :mistakes
|
11
11
|
|
12
|
-
def initialize(code =
|
12
|
+
def initialize(code = "en")
|
13
13
|
@code = code.to_s
|
14
14
|
load_files
|
15
15
|
end
|
@@ -21,23 +21,23 @@ class Lang
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def load_files
|
24
|
-
dirbase = File.join(File.dirname(__FILE__),
|
25
|
-
filepath = File.join(dirbase, @code,
|
24
|
+
dirbase = File.join(File.dirname(__FILE__), "..", "files", "language")
|
25
|
+
filepath = File.join(dirbase, @code, "templates.yaml")
|
26
26
|
@templates = load_yaml_file(filepath)
|
27
|
-
filepath = File.join(dirbase, @code,
|
27
|
+
filepath = File.join(dirbase, @code, "connectors.yaml")
|
28
28
|
@connectors = load_yaml_file(filepath)
|
29
|
-
filepath = File.join(dirbase, @code,
|
29
|
+
filepath = File.join(dirbase, @code, "mistakes.yaml")
|
30
30
|
@mistakes = load_yaml_file(filepath)
|
31
31
|
end
|
32
32
|
|
33
33
|
def load_yaml_file(filepath)
|
34
34
|
begin
|
35
35
|
content = YAML.load(File.new(filepath))
|
36
|
-
rescue
|
37
|
-
Logger.
|
38
|
-
|
39
|
-
Logger.
|
40
|
-
|
36
|
+
rescue => e
|
37
|
+
Logger.error "Lang: YAML loading error (#{filepath})"
|
38
|
+
Logger.error " : Revise apostrophe into string without \\ symbol"
|
39
|
+
Logger.error " : #{e}"
|
40
|
+
exit 1
|
41
41
|
end
|
42
42
|
content
|
43
43
|
end
|
@@ -1,27 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require_relative
|
5
|
-
require_relative
|
3
|
+
require "singleton"
|
4
|
+
require_relative "lang"
|
5
|
+
require_relative "../application"
|
6
|
+
require_relative "../logger"
|
6
7
|
|
7
8
|
##
|
8
|
-
# LangFactory singleton class.
|
9
9
|
# * Read all language codes defined into configuration file
|
10
10
|
# * and load every language
|
11
11
|
# Lang objects are reused
|
12
12
|
class LangFactory
|
13
13
|
include Singleton
|
14
14
|
|
15
|
-
##
|
16
|
-
# Read all language codes from configuration file and load every language
|
17
15
|
def initialize
|
18
|
-
|
16
|
+
# Read all language codes from configuration file and load every language
|
17
|
+
@default = Application.instance.config["languages"]["default"].downcase
|
19
18
|
@langs = {}
|
20
|
-
Application.instance.config[
|
19
|
+
Application.instance.config["languages"].each_pair do |key, value|
|
21
20
|
code = key.downcase
|
22
|
-
next if code ==
|
21
|
+
next if code == "default"
|
23
22
|
|
24
|
-
@langs[code] = Lang.new(code) if value.downcase ==
|
23
|
+
@langs[code] = Lang.new(code) if value.downcase == "yes"
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
@@ -31,15 +30,13 @@ class LangFactory
|
|
31
30
|
def get(code)
|
32
31
|
return @langs[code] unless @langs[code].nil?
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
Logger.error "LangFactory: Unkown Lang code: #{code}"
|
34
|
+
Logger.error " (a) Change input file code lang"
|
35
|
+
Logger.error " (b) Revise configuration from asker.ini"
|
36
|
+
Logger.error " (c) Revise template files"
|
38
37
|
exit 1
|
39
38
|
end
|
40
39
|
|
41
|
-
##
|
42
|
-
# Return default Lang object
|
43
40
|
def default
|
44
41
|
get(@default)
|
45
42
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative "../logger"
|
4
|
+
|
5
5
|
module TextActions
|
6
6
|
##
|
7
|
+
# Set of functions used by Lang class
|
7
8
|
# Return text indicated by lang code...
|
8
9
|
def text_for(option, *input)
|
9
10
|
@_text1 = input[0] # FIXME: done to avoid linter complaints.
|
@@ -14,9 +15,10 @@ module TextActions
|
|
14
15
|
@_text6 = input[5]
|
15
16
|
@_text7 = input[6]
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
if @templates[option].nil?
|
19
|
+
Logger.error "TextActions: Unkown template (#{option})"
|
20
|
+
exit 1
|
21
|
+
end
|
20
22
|
renderer = ERB.new(@templates[option])
|
21
23
|
renderer.result(binding)
|
22
24
|
end
|
@@ -55,12 +57,12 @@ module TextActions
|
|
55
57
|
# @param filter (Boolean) true => apply filter, false => dont filter
|
56
58
|
# @return Array
|
57
59
|
def text_filter_connectors(input, filter)
|
58
|
-
input_lines = input.split(
|
60
|
+
input_lines = input.split(".")
|
59
61
|
output_lines = []
|
60
62
|
output_words = []
|
61
63
|
input_lines.each_with_index do |line, rowindex|
|
62
64
|
row = []
|
63
|
-
line.split(
|
65
|
+
line.split(" ").each_with_index do |word, colindex|
|
64
66
|
flag = @connectors.include? word.downcase
|
65
67
|
|
66
68
|
# if <word> is a conector and <pFilter>==true Then Choose this <word>
|
@@ -72,7 +74,7 @@ module TextActions
|
|
72
74
|
row << word
|
73
75
|
end
|
74
76
|
end
|
75
|
-
row <<
|
77
|
+
row << "."
|
76
78
|
output_lines << row
|
77
79
|
end
|
78
80
|
|
@@ -103,12 +105,12 @@ module TextActions
|
|
103
105
|
lines = input_struct[:lines]
|
104
106
|
indexes = input_indexes.sort
|
105
107
|
counter = 1
|
106
|
-
text =
|
108
|
+
text = ""
|
107
109
|
|
108
110
|
lines.each do |line|
|
109
111
|
line.each do |value|
|
110
112
|
if value.class == String
|
111
|
-
text += (
|
113
|
+
text += (" " + value)
|
112
114
|
elsif value == value.to_i
|
113
115
|
# INFO: ruby 2.4 unifies Fixnum and Bignum into Integer
|
114
116
|
# Avoid using deprecated classes.
|
@@ -117,14 +119,14 @@ module TextActions
|
|
117
119
|
counter += 1
|
118
120
|
else
|
119
121
|
word = input_struct[:words][value][:word]
|
120
|
-
text += (
|
122
|
+
text += (" " + word)
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
124
126
|
end
|
125
|
-
text.gsub!(
|
126
|
-
text.gsub!(
|
127
|
-
text = text[1, text.size] if text[0] ==
|
127
|
+
text.gsub!(" .", ".")
|
128
|
+
text.gsub!(" ,", ",")
|
129
|
+
text = text[1, text.size] if text[0] == " "
|
128
130
|
text
|
129
131
|
end
|
130
132
|
|
@@ -174,20 +176,20 @@ module TextActions
|
|
174
176
|
end
|
175
177
|
return text if text != input
|
176
178
|
|
177
|
-
text +
|
179
|
+
text + "s"
|
178
180
|
end
|
179
181
|
|
180
182
|
def hide_text(input_text)
|
181
183
|
input = input_text.clone
|
182
184
|
if count_words(input) < 2 && input.size < 10
|
183
|
-
output =
|
185
|
+
output = "[*]"
|
184
186
|
else
|
185
|
-
output =
|
187
|
+
output = ""
|
186
188
|
input.each_char do |char|
|
187
189
|
if ' !|"@#$%&/()=?¿¡+*(){}[],.-_<>'.include? char
|
188
190
|
output += char
|
189
191
|
else
|
190
|
-
output +=
|
192
|
+
output += "?"
|
191
193
|
end
|
192
194
|
end
|
193
195
|
end
|