asciidoctor-moodle 1.0.0.dev
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.
- checksums.yaml +7 -0
- data/README.adoc +412 -0
- data/asciidoctor-moodle.gemspec +36 -0
- data/lib/asciidoctor-moodle/cloze_mc/extension.rb +134 -0
- data/lib/asciidoctor-moodle/converter.rb +793 -0
- data/lib/asciidoctor-moodle/drag_drop_text and missing_words/extension.rb +162 -0
- data/lib/asciidoctor-moodle/extensions.rb +34 -0
- data/lib/asciidoctor-moodle/gap/extension.rb +93 -0
- data/lib/asciidoctor-moodle/matching/extension.rb +160 -0
- data/lib/asciidoctor-moodle/multiple_choice/extension.rb +175 -0
- data/lib/asciidoctor-moodle/numerical/extension.rb +163 -0
- data/lib/asciidoctor-moodle/ordering/extension.rb +113 -0
- data/lib/asciidoctor-moodle/question/extension.rb +113 -0
- data/lib/asciidoctor-moodle/question.rb +6 -0
- data/lib/asciidoctor-moodle/short/extension.rb +102 -0
- data/lib/asciidoctor-moodle/true_false/extension.rb +97 -0
- data/lib/asciidoctor-moodle/version.rb +6 -0
- data/lib/asciidoctor-moodle.rb +6 -0
- metadata +105 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
require_relative '../extensions'
|
2
|
+
module Asciidoctor
|
3
|
+
module Question
|
4
|
+
class DDTAndMWBlockProcessor < Extensions::BaseProcessor
|
5
|
+
|
6
|
+
def process(parent, source, tag)
|
7
|
+
docName = parent.attributes['docname']
|
8
|
+
id = tag[:id]
|
9
|
+
err = nil
|
10
|
+
subTypeQuest = tag[:type]
|
11
|
+
question = createQuestion(source.lines, docName,id, subTypeQuest)
|
12
|
+
|
13
|
+
|
14
|
+
stringQuest = question.join(" ")
|
15
|
+
numberQuest= 0
|
16
|
+
copySQ = stringQuest.clone
|
17
|
+
|
18
|
+
|
19
|
+
if subTypeQuest == "DDT" or subTypeQuest =="ddt"
|
20
|
+
ans = prepare_dragbox(copySQ)
|
21
|
+
else
|
22
|
+
ans =prepare_option(copySQ)
|
23
|
+
end
|
24
|
+
|
25
|
+
stringQuest.gsub! /\*(.+?)\*/ do |value|
|
26
|
+
numberQuest+=1
|
27
|
+
prepare_question value.gsub('*', ''), numberQuest
|
28
|
+
end
|
29
|
+
stringQuest << ans
|
30
|
+
|
31
|
+
new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "#{docName}question_#{id}_#{subTypeQuest}"}}
|
32
|
+
|
33
|
+
|
34
|
+
reader = Asciidoctor::Reader.new stringQuest
|
35
|
+
|
36
|
+
|
37
|
+
loop do
|
38
|
+
block = Asciidoctor::Parser.next_block reader, new_parent
|
39
|
+
|
40
|
+
break if block.nil?
|
41
|
+
|
42
|
+
if block.context == :listing
|
43
|
+
|
44
|
+
block.subs.push :macros
|
45
|
+
block.subs.push :quotes
|
46
|
+
end
|
47
|
+
new_parent.blocks.push block
|
48
|
+
end
|
49
|
+
|
50
|
+
if err.nil?
|
51
|
+
|
52
|
+
post_answers new_parent, tag
|
53
|
+
else
|
54
|
+
process_error_push new_parent, err, source.lines
|
55
|
+
end
|
56
|
+
|
57
|
+
new_parent
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
class MOODLEDDTAndMWBlockProcessor < DDTAndMWBlockProcessor
|
65
|
+
|
66
|
+
|
67
|
+
def createQuestion (question, docName, id, subTypeQuest)
|
68
|
+
if subTypeQuest == 'DDT' or subTypeQuest == 'ddt'
|
69
|
+
type="ddwtos"
|
70
|
+
else
|
71
|
+
type = "gapselect"
|
72
|
+
end
|
73
|
+
preQuest = " <question type=\"#{type}\">
|
74
|
+
<name>
|
75
|
+
<text>#{docName}_question_#{id}_#{subTypeQuest}</text>
|
76
|
+
</name>
|
77
|
+
<questiontext format=\"html\">
|
78
|
+
<text><![CDATA[ <p>"
|
79
|
+
|
80
|
+
posQuest = "</p> ]]></text>
|
81
|
+
</questiontext>
|
82
|
+
<generalfeedback format=\"html\">
|
83
|
+
<text></text>
|
84
|
+
</generalfeedback>
|
85
|
+
<defaultgrade>1</defaultgrade>
|
86
|
+
<penalty>0.3333333</penalty>
|
87
|
+
<hidden>0</hidden>
|
88
|
+
<idnumber></idnumber>
|
89
|
+
<shuffleanswers>1</shuffleanswers>
|
90
|
+
<correctfeedback format=\"html\">
|
91
|
+
<text><![CDATA[<p>Your answer is correct.</p>]]></text>
|
92
|
+
</correctfeedback>
|
93
|
+
<partiallycorrectfeedback format=\"html\">
|
94
|
+
<text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
|
95
|
+
</partiallycorrectfeedback>
|
96
|
+
<incorrectfeedback format=\"html\">
|
97
|
+
<text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
|
98
|
+
</incorrectfeedback>
|
99
|
+
<shownumcorrect/>"
|
100
|
+
question = [question.join("</p> <p> ")] #Create the newline
|
101
|
+
|
102
|
+
question.prepend(preQuest)
|
103
|
+
question.prepend("+++")
|
104
|
+
|
105
|
+
question.push(posQuest)
|
106
|
+
question.push("+++")
|
107
|
+
end
|
108
|
+
|
109
|
+
def prepare_question(value, tag)
|
110
|
+
"[[#{tag}]]"
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
def recup_ans(copySQ)
|
115
|
+
answers = Array.new
|
116
|
+
regex = %r{(\*.+?\*)}
|
117
|
+
matchData = regex.match(copySQ)
|
118
|
+
begin
|
119
|
+
answers.push matchData.captures[0]
|
120
|
+
copySQ.gsub!(matchData.captures[0],"")
|
121
|
+
matchData = regex.match(copySQ)
|
122
|
+
end while matchData != nil
|
123
|
+
|
124
|
+
answers.each do |value|
|
125
|
+
value.gsub!("*","")
|
126
|
+
end
|
127
|
+
answers
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
def prepare_dragbox(copySQ)
|
132
|
+
answers = recup_ans(copySQ)
|
133
|
+
dragbox ="+++"
|
134
|
+
answers.each do |val|
|
135
|
+
dragbox << "<dragbox>
|
136
|
+
<text>#{val}</text>
|
137
|
+
<group>1</group>
|
138
|
+
</dragbox> \n"
|
139
|
+
end
|
140
|
+
dragbox <<"</question> +++"
|
141
|
+
end
|
142
|
+
|
143
|
+
def prepare_option(copySQ)
|
144
|
+
answers = recup_ans(copySQ)
|
145
|
+
dragbox ="+++"
|
146
|
+
answers.each do |val|
|
147
|
+
dragbox << " <selectoption>
|
148
|
+
<text>#{val}</text>
|
149
|
+
<group>1</group>
|
150
|
+
</selectoption> \n"
|
151
|
+
end
|
152
|
+
dragbox <<"</question> +++"
|
153
|
+
end
|
154
|
+
|
155
|
+
def post_answers(parent, tag)
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'asciidoctor' unless defined? ::Asciidoctor::VERSION
|
2
|
+
require 'asciidoctor/extensions'
|
3
|
+
|
4
|
+
require_relative 'version'
|
5
|
+
|
6
|
+
module Asciidoctor
|
7
|
+
module Question
|
8
|
+
module Extensions
|
9
|
+
class BaseProcessor < Asciidoctor::Extensions::BlockProcessor
|
10
|
+
use_dsl
|
11
|
+
|
12
|
+
def self.inherited(subclass)
|
13
|
+
subclass.option :contexts, [:example, :literal, :open]
|
14
|
+
subclass.option :content_model, :simple
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_error(parent, err, source_lines)
|
18
|
+
lines = ['[NOTE]', '====', 'Error ! ' + err, '====']
|
19
|
+
block = Asciidoctor::Parser.next_block Asciidoctor::Reader.new(lines), parent
|
20
|
+
block.blocks.push Asciidoctor::Parser.next_block Asciidoctor::Reader.new(['[source, asciidoc]', '----'] + source_lines + ['----']), block
|
21
|
+
block
|
22
|
+
end
|
23
|
+
|
24
|
+
def process_error_push(parent, err, source_lines)
|
25
|
+
parent.blocks.push process_error parent, err, source_lines
|
26
|
+
end
|
27
|
+
|
28
|
+
def post_answers(parent, tag)
|
29
|
+
parent
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require_relative '../extensions'
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Question
|
5
|
+
class GAPBlockProcessor < Extensions::BaseProcessor
|
6
|
+
|
7
|
+
def process(parent, source, tag)
|
8
|
+
docName = parent.attributes['docname']
|
9
|
+
id = tag[:id]
|
10
|
+
err = nil
|
11
|
+
|
12
|
+
question = prepare_question(source.lines, docName,id)
|
13
|
+
stringQuest = question.join(" ")
|
14
|
+
|
15
|
+
stringQuest.gsub! /__([^_]+?)__/ do |value|
|
16
|
+
prepare_gap value.gsub('_', ''), tag
|
17
|
+
end
|
18
|
+
|
19
|
+
new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "#{docName}question_#{id}_gap"}}
|
20
|
+
|
21
|
+
|
22
|
+
reader = Asciidoctor::Reader.new stringQuest
|
23
|
+
|
24
|
+
|
25
|
+
loop do
|
26
|
+
block = Asciidoctor::Parser.next_block reader, new_parent
|
27
|
+
|
28
|
+
break if block.nil?
|
29
|
+
|
30
|
+
if block.context == :listing
|
31
|
+
|
32
|
+
block.subs.push :macros
|
33
|
+
block.subs.push :quotes
|
34
|
+
end
|
35
|
+
new_parent.blocks.push block
|
36
|
+
end
|
37
|
+
|
38
|
+
if err.nil?
|
39
|
+
|
40
|
+
post_answers new_parent, tag
|
41
|
+
else
|
42
|
+
process_error_push new_parent, err, source.lines
|
43
|
+
end
|
44
|
+
|
45
|
+
new_parent
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def prepare_gap(value, tag)
|
50
|
+
value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
class MOODLEGAPBlockProcessor < GAPBlockProcessor
|
57
|
+
|
58
|
+
def prepare_gap(value, tag)
|
59
|
+
" {1:SHORTANSWER:%100%#{value}} "
|
60
|
+
end
|
61
|
+
|
62
|
+
def prepare_question(question, docName, id)
|
63
|
+
preQuest = " <question type=\"cloze\">
|
64
|
+
<name>
|
65
|
+
<text>#{docName}_question_#{id}_gap </text>
|
66
|
+
</name>
|
67
|
+
<questiontext format=\"html\">
|
68
|
+
<text><![CDATA[ "
|
69
|
+
|
70
|
+
posQuest = " ]]></text>
|
71
|
+
</questiontext>
|
72
|
+
<generalfeedback format=\"html\">
|
73
|
+
<text></text>
|
74
|
+
</generalfeedback>
|
75
|
+
<penalty>0.3333333</penalty>
|
76
|
+
<hidden>0</hidden>
|
77
|
+
<idnumber></idnumber>
|
78
|
+
</question>"
|
79
|
+
|
80
|
+
|
81
|
+
question.prepend("+++")
|
82
|
+
question.prepend(preQuest)
|
83
|
+
question.prepend("+++")
|
84
|
+
question.push("+++")
|
85
|
+
question.push(posQuest)
|
86
|
+
question.push("+++")
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require_relative '../extensions'
|
2
|
+
#On peut utiliser l'italique ou le gras pour la question
|
3
|
+
module Asciidoctor
|
4
|
+
module Question
|
5
|
+
|
6
|
+
class MatchingBlockProcessor < Extensions::BaseProcessor
|
7
|
+
|
8
|
+
def nbQuestion(lines)
|
9
|
+
nbQuest = 0
|
10
|
+
lines.map do |answer|
|
11
|
+
if quest =~ /^-\s?/
|
12
|
+
nbQuest +=1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
nbQuest
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def splitQuestAndSubQuest(lines)
|
20
|
+
quest = Array.new
|
21
|
+
subQuest = Array.new
|
22
|
+
nbSubQuest = 0
|
23
|
+
|
24
|
+
lines.each do |line|
|
25
|
+
switch = true if line =~ /(^-|^\*)\s/
|
26
|
+
if switch
|
27
|
+
line.sub!(/(^-|^\*)\s/, "")
|
28
|
+
nbSubQuest +=1
|
29
|
+
subQuest.push line
|
30
|
+
else
|
31
|
+
quest.push line
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
[nbSubQuest, quest, subQuest]
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def process(parent, source, tag)
|
40
|
+
|
41
|
+
size = tag.size
|
42
|
+
docName = parent.attributes['docname']
|
43
|
+
id = tag[:id]
|
44
|
+
err = '+++ You need at least 2 questions and one answer for each of them! +++'
|
45
|
+
lines = source.lines #Copy of the remaining Array of String lines managed by the reader
|
46
|
+
nbSubQuest, quest, subQuest = splitQuestAndSubQuest(lines)
|
47
|
+
|
48
|
+
answers = Array.new
|
49
|
+
tag.each { |key, val| answers.push val if key.class==Integer && key>2 && key< size-3} #Get the tag's answers
|
50
|
+
nbAns = answers.size
|
51
|
+
|
52
|
+
quest = prepare_question_lines(quest, docName, id, nbSubQuest)
|
53
|
+
|
54
|
+
subQuestAndAns = prepare_subQuest subQuest, answers
|
55
|
+
|
56
|
+
|
57
|
+
new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "#{docName}_question_#{id}_matching"}}
|
58
|
+
|
59
|
+
|
60
|
+
if nbAns>= nbSubQuest && nbAns>=2 && nbSubQuest>=2
|
61
|
+
reader = Asciidoctor::Reader.new(quest)
|
62
|
+
loop do
|
63
|
+
block = Asciidoctor::Parser.next_block reader, new_parent
|
64
|
+
break if block.nil?
|
65
|
+
new_parent.blocks.push block
|
66
|
+
end
|
67
|
+
|
68
|
+
reader = Asciidoctor::Reader.new(subQuestAndAns)
|
69
|
+
answers_block = Asciidoctor::Parser.next_block reader, new_parent
|
70
|
+
new_parent.blocks.push answers_block
|
71
|
+
post_answers new_parent, tag
|
72
|
+
|
73
|
+
else
|
74
|
+
process_error_push new_parent, err, answers
|
75
|
+
end
|
76
|
+
new_parent
|
77
|
+
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def prepare_answer_lines(lines)
|
82
|
+
lines
|
83
|
+
end
|
84
|
+
|
85
|
+
def prepare_answers(answers_block, tag)
|
86
|
+
answers_block.blocks.shuffle! if tag[:shuffle] == 'shuffle'
|
87
|
+
answers_block
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
class MOODLEMatchingBlockProcessor < MatchingBlockProcessor
|
94
|
+
|
95
|
+
def prepare_subQuest(subQuest, answers)
|
96
|
+
nbSub = subQuest.size
|
97
|
+
nbAns = answers.size
|
98
|
+
text="+++ "
|
99
|
+
|
100
|
+
preSubQuest = '<subquestion format="html">
|
101
|
+
<text><![CDATA[<p> '
|
102
|
+
postSubQuest = '</p>]]></text>
|
103
|
+
<answer>
|
104
|
+
<text>'
|
105
|
+
noSubQuest = "<subquestion format=\"html\">
|
106
|
+
<text/>
|
107
|
+
<answer>
|
108
|
+
<text>"
|
109
|
+
postAns = "</text>
|
110
|
+
</answer>
|
111
|
+
</subquestion>"
|
112
|
+
|
113
|
+
nbAns.times do |i|
|
114
|
+
if i<nbSub
|
115
|
+
text << preSubQuest << subQuest[i] << postSubQuest << answers[i] <<postAns
|
116
|
+
else
|
117
|
+
text << noSubQuest << answers[i] <<postAns
|
118
|
+
end
|
119
|
+
end
|
120
|
+
text << '</question> +++'
|
121
|
+
text
|
122
|
+
end
|
123
|
+
|
124
|
+
def prepare_question_lines(question, docName,id,nbSubQuest )
|
125
|
+
|
126
|
+
preQuest = "+++ <question type=\"matching\">
|
127
|
+
<name>
|
128
|
+
<text> #{docName}_question_#{id}_matching </text>
|
129
|
+
</name>
|
130
|
+
<questiontext format=\"html\">
|
131
|
+
<text><![CDATA[<p> +++"
|
132
|
+
postQuest = "+++ </p>]]></text>
|
133
|
+
</questiontext>
|
134
|
+
<generalfeedback format=\"html\">
|
135
|
+
<text></text>
|
136
|
+
</generalfeedback>
|
137
|
+
<defaultgrade>#{nbSubQuest}</defaultgrade>
|
138
|
+
<penalty>1</penalty>
|
139
|
+
<hidden>0</hidden>
|
140
|
+
<idnumber></idnumber>
|
141
|
+
<shuffleanswers>true</shuffleanswers>
|
142
|
+
<correctfeedback format=\"html\">
|
143
|
+
<text><![CDATA[<p>Your answer is correct.</p>]]></text>
|
144
|
+
</correctfeedback>
|
145
|
+
<partiallycorrectfeedback format=\"html\">
|
146
|
+
<text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
|
147
|
+
</partiallycorrectfeedback>
|
148
|
+
<incorrectfeedback format=\"html\">
|
149
|
+
<text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
|
150
|
+
</incorrectfeedback>
|
151
|
+
<shownumcorrect/> +++"
|
152
|
+
|
153
|
+
question.prepend(preQuest)
|
154
|
+
question.push(postQuest)
|
155
|
+
|
156
|
+
question
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require_relative '../extensions'
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Question
|
5
|
+
|
6
|
+
class MultipleChoiceBlockProcessor < Extensions::BaseProcessor
|
7
|
+
|
8
|
+
def nbTrueF(lines)
|
9
|
+
nbTrue = 0
|
10
|
+
lines.map do |answer|
|
11
|
+
if answer =~ /^-\s?\[(X|\*)\]/
|
12
|
+
nbTrue +=1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
nbTrue
|
16
|
+
end
|
17
|
+
|
18
|
+
def process(parent, source, tag)
|
19
|
+
|
20
|
+
docName = parent.attributes['docname']
|
21
|
+
id = tag[:id]
|
22
|
+
err = '+++ Error : there is no answer +++'
|
23
|
+
question = Array.new
|
24
|
+
answers = Array.new
|
25
|
+
switch = false
|
26
|
+
nbAnswer = 0
|
27
|
+
|
28
|
+
valShuffleNamed = tag["shuffle"]
|
29
|
+
|
30
|
+
valShuffle = tag[3]
|
31
|
+
|
32
|
+
if valShuffle == 'shuffle' || valShuffle == 'SHUFFLE' || valShuffleNamed == 'shuffle' || valShuffleNamed == 'SHUFFLE'
|
33
|
+
isShuffle = true
|
34
|
+
else
|
35
|
+
isShuffle = false
|
36
|
+
end
|
37
|
+
|
38
|
+
source.lines.each do |line|
|
39
|
+
switch = true if line =~ /^-\s?\[/
|
40
|
+
if switch
|
41
|
+
nbAnswer +=1
|
42
|
+
answers.push line
|
43
|
+
else
|
44
|
+
question.push line
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
answers, nbTrue = prepare_answer_lines answers
|
49
|
+
|
50
|
+
if nbTrue <= 1
|
51
|
+
question = prepare_question_lines(question, docName,id, isShuffle,true)
|
52
|
+
else
|
53
|
+
question = prepare_question_lines(question, docName,id, isShuffle,false)
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "#{docName}_question_#{id}_mc"}}
|
58
|
+
|
59
|
+
if nbAnswer>0
|
60
|
+
reader = Asciidoctor::Reader.new(question)
|
61
|
+
loop do
|
62
|
+
block = Asciidoctor::Parser.next_block reader, new_parent
|
63
|
+
break if block.nil?
|
64
|
+
new_parent.blocks.push block
|
65
|
+
end
|
66
|
+
|
67
|
+
reader = Asciidoctor::Reader.new(answers)
|
68
|
+
answers_block = Asciidoctor::Parser.next_block reader, new_parent
|
69
|
+
new_parent.blocks.push answers_block
|
70
|
+
post_answers new_parent, tag
|
71
|
+
|
72
|
+
else
|
73
|
+
|
74
|
+
process_error_push new_parent, err, answers
|
75
|
+
end
|
76
|
+
new_parent
|
77
|
+
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def prepare_answer_lines(lines)
|
82
|
+
lines
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
class MOODLEMultipleChoiceBlockProcessor < MultipleChoiceBlockProcessor
|
88
|
+
|
89
|
+
def nbTrueF(lines)
|
90
|
+
nbTrue = 0
|
91
|
+
lines.map do |answer|
|
92
|
+
if answer =~ /^-\s?\[(X|\*)\]/
|
93
|
+
nbTrue +=1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
nbTrue
|
97
|
+
end
|
98
|
+
|
99
|
+
def prepare_answer_lines(lines)
|
100
|
+
|
101
|
+
nbTrue = nbTrueF(lines)
|
102
|
+
valFraction = (100.0 / nbTrue)
|
103
|
+
penality = -33.3333
|
104
|
+
noPenality = 0
|
105
|
+
if nbTrue >1
|
106
|
+
fract = penality
|
107
|
+
else
|
108
|
+
fract = noPenality
|
109
|
+
end
|
110
|
+
preAnsFaux = "<answer fraction=\"#{fract}\" format=\"html\">
|
111
|
+
<text>"
|
112
|
+
preAnsVrai = "<answer fraction=\"#{valFraction}\" format=\"html\">
|
113
|
+
<text>"
|
114
|
+
postAns = ' </text>
|
115
|
+
<feedback format="html">
|
116
|
+
<text></text>
|
117
|
+
</feedback>
|
118
|
+
</answer>'
|
119
|
+
|
120
|
+
lines.map! do |answer|
|
121
|
+
if answer =~ /^-\s?\[\s?\]/
|
122
|
+
answer.sub!(/^-\s?\[\s\]/, preAnsFaux)
|
123
|
+
answer << postAns
|
124
|
+
elsif answer =~ /^-\s?\[(X|\*)\]/
|
125
|
+
answer.sub!(/^-\s?\[(X|\*)\]/, preAnsVrai)
|
126
|
+
answer << postAns
|
127
|
+
else
|
128
|
+
answer
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
lines.prepend("+++")
|
133
|
+
lines.push('</question>')
|
134
|
+
lines.push('+++')
|
135
|
+
[lines, nbTrue]
|
136
|
+
end
|
137
|
+
|
138
|
+
def prepare_question_lines(lines, docName,id, isShuffle, is_single)
|
139
|
+
|
140
|
+
preQuest = "+++ <question type=\"multichoice\">
|
141
|
+
<name>
|
142
|
+
<text> #{docName}_question_#{id}_mc </text>
|
143
|
+
</name>
|
144
|
+
<questiontext format=\"html\">
|
145
|
+
<text><![CDATA[<p> +++"
|
146
|
+
postQuest = "+++ </p>]]></text>
|
147
|
+
</questiontext>
|
148
|
+
<generalfeedback format=\"html\">
|
149
|
+
<text></text>
|
150
|
+
</generalfeedback>
|
151
|
+
<defaultgrade>1</defaultgrade>
|
152
|
+
<penalty>0.3333333</penalty>
|
153
|
+
<hidden>0</hidden>
|
154
|
+
<idnumber></idnumber>
|
155
|
+
<single>#{is_single}</single>
|
156
|
+
<shuffleanswers>#{isShuffle}</shuffleanswers>
|
157
|
+
<answernumbering>abc</answernumbering>
|
158
|
+
<showstandardinstruction>1</showstandardinstruction>
|
159
|
+
<correctfeedback format=\"html\">
|
160
|
+
<text></text>
|
161
|
+
</correctfeedback>
|
162
|
+
<partiallycorrectfeedback format=\"html\">
|
163
|
+
<text></text>
|
164
|
+
</partiallycorrectfeedback>
|
165
|
+
<incorrectfeedback format=\"html\">
|
166
|
+
<text></text>
|
167
|
+
</incorrectfeedback> +++"
|
168
|
+
|
169
|
+
lines.prepend(preQuest)
|
170
|
+
lines.push(postQuest)
|
171
|
+
lines
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|