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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7cda5ba859d51bb5e75a9e32456dbeb68f0bc692981cd87ceffa38a2e1416592
|
4
|
+
data.tar.gz: 99805f9c1e42aabf270a9259b0b82956cf90688065980f0b1173c81f7a769db8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ceb40738246d082023478f9c41a679a71d7443a24e1b0bb9ab298eb3fb2b2657d253b7eae3817dcc73bea1afd66735d7065827793a3f1ae2df202fe934d8a3f9
|
7
|
+
data.tar.gz: 70a2864be96d9f85f8ea51ee0b03899a7860f3c92e237a9a83b2a6458b5867a975efdbe5e83dacf9d95a6344288162ab74bb73fe6030db9634f9ecbc5f237748
|
data/README.adoc
ADDED
@@ -0,0 +1,412 @@
|
|
1
|
+
[source,asciidoc]
|
2
|
+
|
3
|
+
= Asciidoctor Moodle-Question
|
4
|
+
ifndef::imagesdir[:imagesdir: images]
|
5
|
+
|
6
|
+
:description: README for the Asciidoctor Moodle-Question extension for Asciidoctor, based on Asciidoctor-Question.
|
7
|
+
:version: 0.0.1
|
8
|
+
|
9
|
+
image:https://img.shields.io/badge/license-MIT-blue.svg[MIT License, link=#copyright]
|
10
|
+
|
11
|
+
Asciidoctor Moodle-Question is a set of Asciidoctor extensions that allows you to add questions as multiple choice and gap text and convert them to Moodle XML format. The questions are defined using plain text in your AsciiDoc document.
|
12
|
+
|
13
|
+
== Creating a Question
|
14
|
+
|
15
|
+
A question is written inside a literal block, which needs at least two attributes.
|
16
|
+
|
17
|
+
.Anatomy of a question
|
18
|
+
----
|
19
|
+
[question, question-type] // <1> <2>
|
20
|
+
.... // <3>
|
21
|
+
Question in appropriate syntax
|
22
|
+
....
|
23
|
+
----
|
24
|
+
<1> The first positional attribute in the attribute list specifies that this block is a question.
|
25
|
+
<2> The second positional attribute defines the type of this question (mc or gap)
|
26
|
+
<3> Place the attribute list directly on top of the delimited literal block (+....+). You can also use an example (+====+) or open block (`--`) as an alternative.
|
27
|
+
|
28
|
+
The following question types are available:
|
29
|
+
|
30
|
+
I used HTML <p> to format the output in Moodle to fit the tabular's case.
|
31
|
+
|
32
|
+
.Resume
|
33
|
+
[cols="2,3a,3a",options="header"]
|
34
|
+
|===
|
35
|
+
|Question type |Input |Output
|
36
|
+
|
37
|
+
|mc
|
38
|
+
|[source]
|
39
|
+
----
|
40
|
+
[question, mc]
|
41
|
+
....
|
42
|
+
Which of these are capitals ?
|
43
|
+
|
44
|
+
- [X] Romes
|
45
|
+
- [ ] Sydney
|
46
|
+
- [X] Paris
|
47
|
+
....
|
48
|
+
----
|
49
|
+
|image::mc.png[]
|
50
|
+
|
51
|
+
|gap
|
52
|
+
|[source]
|
53
|
+
----
|
54
|
+
[question, gap]
|
55
|
+
....
|
56
|
+
<p> If debugging is the process of removing </p>
|
57
|
+
<p> software bugs, then programming must be </p>
|
58
|
+
<p> the process of __putting them in__. </p>
|
59
|
+
- Edsger Dijkstra
|
60
|
+
....
|
61
|
+
----
|
62
|
+
|image::gap.png[]
|
63
|
+
|
64
|
+
|
65
|
+
|tf
|
66
|
+
|[source]
|
67
|
+
----
|
68
|
+
[question, TF, True]
|
69
|
+
....
|
70
|
+
<p> Donald Knuth said : </p>
|
71
|
+
<p> "Premature optimization is the
|
72
|
+
root of all evil." </p>
|
73
|
+
....
|
74
|
+
----
|
75
|
+
|image::tf.png[]
|
76
|
+
|
77
|
+
|matching
|
78
|
+
|[source]
|
79
|
+
----
|
80
|
+
[question, matching,
|
81
|
+
wrote the first computer programme in the world,
|
82
|
+
decrypted Enigma machine's messages,
|
83
|
+
invented the merge sort algorithm]
|
84
|
+
....
|
85
|
+
Match each author with his contribution ?
|
86
|
+
|
87
|
+
- Ada Lovelace :
|
88
|
+
|
89
|
+
- Alan Turing :
|
90
|
+
....
|
91
|
+
----
|
92
|
+
|image::match.png[]
|
93
|
+
|
94
|
+
|cmc
|
95
|
+
|[source]
|
96
|
+
----
|
97
|
+
[question, CMC, Merge sort algorithm, Bombe]
|
98
|
+
====
|
99
|
+
John von Neumann's invented
|
100
|
+
|
101
|
+
* Merge sort algorithm
|
102
|
+
* Quicksort algorithm
|
103
|
+
* ShellSort algorithm
|
104
|
+
|
105
|
+
<p>
|
106
|
+
Enigma's message machine was decrypted by
|
107
|
+
</p>
|
108
|
+
|
109
|
+
- Bombe
|
110
|
+
- Decryptma
|
111
|
+
- Decrypte's machine
|
112
|
+
====
|
113
|
+
----
|
114
|
+
|image::cmc.png[]
|
115
|
+
|
116
|
+
|ordering
|
117
|
+
|[source]
|
118
|
+
----
|
119
|
+
[question, ordering]
|
120
|
+
....
|
121
|
+
Arrange the layers with the deepest at the bottom:
|
122
|
+
|
123
|
+
* VM
|
124
|
+
* OS
|
125
|
+
* Material
|
126
|
+
....
|
127
|
+
----
|
128
|
+
|image::order.png[]
|
129
|
+
|
130
|
+
|ddt
|
131
|
+
|[source]
|
132
|
+
----
|
133
|
+
[question, ddt]
|
134
|
+
....
|
135
|
+
“Computers are good at *following instructions*,
|
136
|
+
but not at *reading your mind*.”
|
137
|
+
– Donald Knuth,
|
138
|
+
the “father of analysis of algorithms”
|
139
|
+
....
|
140
|
+
----
|
141
|
+
|image::ddt.png[]
|
142
|
+
|
143
|
+
|short
|
144
|
+
|[source]
|
145
|
+
----
|
146
|
+
[question, short, Paris, case=case]
|
147
|
+
....
|
148
|
+
What city is the capital of France ?
|
149
|
+
....
|
150
|
+
----
|
151
|
+
|image::short.png[]
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
|num
|
156
|
+
|[source]
|
157
|
+
----
|
158
|
+
[question, num, unit="cm=1,dm=0.1",tolerance=1, ans=4]
|
159
|
+
====
|
160
|
+
2cm + 2cm =
|
161
|
+
====
|
162
|
+
----
|
163
|
+
|image::numerical.png[]
|
164
|
+
|
165
|
+
|mw
|
166
|
+
|[source]
|
167
|
+
----
|
168
|
+
[question, mw]
|
169
|
+
....
|
170
|
+
“Computers are good at *following instructions*, but not at *reading your mind*.”
|
171
|
+
– Donald Knuth, the “father of analysis of algorithms”
|
172
|
+
....
|
173
|
+
----
|
174
|
+
|image::mw.png[]
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|===
|
180
|
+
|
181
|
+
=== Generating a Question Document from a Terminal
|
182
|
+
|
183
|
+
You can load Asciidoctor question in a terminal using the -r (require) and -b (backend) flags.
|
184
|
+
[source]
|
185
|
+
----
|
186
|
+
asciidoctor -r asciidoctor-moodle -b moodle sample.adoc
|
187
|
+
|
188
|
+
----
|
189
|
+
|
190
|
+
|
191
|
+
=== Details format
|
192
|
+
|
193
|
+
==== +++<u> MC (multiple choice question) : </u>+++
|
194
|
+
[source]
|
195
|
+
----
|
196
|
+
[question, mc|MC, shuffle=shuffle] //Used of the named attributes.
|
197
|
+
----
|
198
|
+
[source]
|
199
|
+
----
|
200
|
+
[question, mc|MC, shuffle] //Or just set the third attribute.
|
201
|
+
----
|
202
|
+
If you want the answers to be shuffle for each try. You can either use 'MC' or 'mc'.
|
203
|
+
|
204
|
+
[source]
|
205
|
+
----
|
206
|
+
- [X] correct1
|
207
|
+
- [*] correct2
|
208
|
+
- [ ] false
|
209
|
+
----
|
210
|
+
|
211
|
+
You can either tick the correct(s) answer(s) with X or *.
|
212
|
+
|
213
|
+
The question is on 1 point, the point you receive for a good answer is 1/nbCorrectAnswersPossibles.
|
214
|
+
|
215
|
+
WARNING: You need space bewteen [ ] if it's false.
|
216
|
+
|
217
|
+
==== +++<u>Gap (gap fill question) </u>+++
|
218
|
+
|
219
|
+
You gap your text with :
|
220
|
+
[source]
|
221
|
+
----
|
222
|
+
The gap is __here__
|
223
|
+
----
|
224
|
+
|
225
|
+
You gain 1 point for each gap correctly fill.
|
226
|
+
|
227
|
+
==== +++<u>TF (true or false question) </u>+++
|
228
|
+
|
229
|
+
You can only write one question by question's block. One point for each question's block.
|
230
|
+
|
231
|
+
[cols="2a,2a",options="header"]
|
232
|
+
|===
|
233
|
+
|Good
|
234
|
+
|Bad
|
235
|
+
|
|
236
|
+
[source]
|
237
|
+
----
|
238
|
+
[question, TF, true]
|
239
|
+
....
|
240
|
+
Question to which correct answer is true
|
241
|
+
....
|
242
|
+
|
243
|
+
[question, TF, false]
|
244
|
+
....
|
245
|
+
Question to which correct answer is false
|
246
|
+
....
|
247
|
+
----
|
248
|
+
|
|
249
|
+
[source]
|
250
|
+
----
|
251
|
+
[question, TF, true, false]
|
252
|
+
....
|
253
|
+
Question to which correct answer is true
|
254
|
+
|
255
|
+
Question to which correct answer is false
|
256
|
+
....
|
257
|
+
----
|
258
|
+
|===
|
259
|
+
|
260
|
+
|
261
|
+
==== +++<u>Matching (matching question)</u>+++
|
262
|
+
|
263
|
+
The matching question is based on a pool of questions/text and a pool of answers.
|
264
|
+
|
265
|
+
The pool of answers is shared by all the questions/text.
|
266
|
+
|
267
|
+
Each questions is linked to a correct answer.
|
268
|
+
|
269
|
+
It's represented as a dropdown menu in-line in the text.
|
270
|
+
|
271
|
+
[source]
|
272
|
+
----
|
273
|
+
[question, matching, Answer1, Answer2, Answer3]
|
274
|
+
....
|
275
|
+
General text need.
|
276
|
+
|
277
|
+
- Sentence1 :
|
278
|
+
|
279
|
+
- Sentence2 :
|
280
|
+
....
|
281
|
+
----
|
282
|
+
In this exemple the first sentence (Sentence1) match the first argument (Answer1) after 'matching'.
|
283
|
+
|
284
|
+
The second second sentence (Sentence2) match the second argument (Answer2) after 'matching'.
|
285
|
+
|
286
|
+
Answer3 isn't linked to any sentence but it will still be part of the pool of possible answers.
|
287
|
+
|
288
|
+
TIP: You can use either * or - for listing the sentences.
|
289
|
+
|
290
|
+
WARNING: Depending on your Moodle's version you will need at least 2 questions and 3 answers or one answer for each question if there is more than 2 questions, to be imported correctly.
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
==== +++<u>CMC (cloze mutliple choice)</u>+++
|
295
|
+
Unlike matching questions, each CMC question has it own pool of answers.
|
296
|
+
|
297
|
+
Each questions is linked to a correct answer.
|
298
|
+
|
299
|
+
It's represented as a dropdown menu in-line in the text.
|
300
|
+
|
301
|
+
You can use either a delimiter or a block list format to write the possible answers.
|
302
|
+
|
303
|
+
[cols="2a,2a",options="header"]
|
304
|
+
|===
|
305
|
+
|List
|
306
|
+
|Delimiter
|
307
|
+
|
|
308
|
+
[source]
|
309
|
+
----
|
310
|
+
|
311
|
+
[question, CMC, Correct1, Correct2]
|
312
|
+
====
|
313
|
+
|
314
|
+
Question 1
|
315
|
+
|
316
|
+
* False1
|
317
|
+
* AlsoFalse1
|
318
|
+
* Correct1
|
319
|
+
|
320
|
+
Question 2
|
321
|
+
|
322
|
+
- Correct2
|
323
|
+
- False2
|
324
|
+
- AlsoFalse2
|
325
|
+
|
326
|
+
====
|
327
|
+
----
|
328
|
+
|
|
329
|
+
[source]
|
330
|
+
--
|
331
|
+
[question, CMC, Correct1, Correct2]
|
332
|
+
====
|
333
|
+
|
334
|
+
Question 1
|
335
|
+
|
336
|
+
----
|
337
|
+
* False1
|
338
|
+
* AlsoFalse1
|
339
|
+
* Correct1
|
340
|
+
----
|
341
|
+
Question 2
|
342
|
+
|
343
|
+
----
|
344
|
+
- Correct2
|
345
|
+
- False2
|
346
|
+
- AlsoFalse2
|
347
|
+
----
|
348
|
+
====
|
349
|
+
--
|
350
|
+
|===
|
351
|
+
|
352
|
+
TIP: You can use either * or - to enumerate the answers, whether you are using a List or a delimiter.
|
353
|
+
|
354
|
+
WARNING: For delimiter of a list you can only use ---- or ====, -- won't work.
|
355
|
+
|
356
|
+
WARNING: If you don't have a correct answer for each question, Moodle won't accept your file.
|
357
|
+
|
358
|
+
|
359
|
+
==== +++<u>Ordering</u>+++
|
360
|
+
|
361
|
+
You need to list the items in the same order as the correct answer. Moodle will shuffle them.
|
362
|
+
|
363
|
+
TIP: You can use either * or - for listing the sentences.
|
364
|
+
|
365
|
+
WARNING: Depending on your version of Moodle, you will need at least 2 or 3 items in the list for it to be imported correctly.
|
366
|
+
|
367
|
+
==== +++<u>DDT (drag and drop into text) and MW (missing Words)</u>+++
|
368
|
+
|
369
|
+
Simply enclose the portion of the text you with to label with asterisks (*).
|
370
|
+
|
371
|
+
You can't have more draggable texts (possible answers) than gaps.
|
372
|
+
|
373
|
+
WARNING: The text you enclose needs to be on the same line to be imported correctly.
|
374
|
+
|
375
|
+
[cols="2a,2a",options="header"]
|
376
|
+
|===
|
377
|
+
|Good
|
378
|
+
|Bad
|
379
|
+
|
|
380
|
+
[source]
|
381
|
+
----
|
382
|
+
[question, ddt]
|
383
|
+
....
|
384
|
+
“Computers are good at *following instructions*,
|
385
|
+
but not at *reading your mind*.”
|
386
|
+
– Donald Knuth, the “father of analysis of algorithms”
|
387
|
+
....
|
388
|
+
----
|
389
|
+
|
|
390
|
+
[source]
|
391
|
+
--
|
392
|
+
[question, ddt]
|
393
|
+
....
|
394
|
+
“Computers are good at *following
|
395
|
+
instructions,* but not at*reading *your* mind.”
|
396
|
+
– Donald Knuth, the “father of analysis of algorithms”
|
397
|
+
....
|
398
|
+
--
|
399
|
+
|===
|
400
|
+
|
401
|
+
==== +++<u>Short (answer)</u>+++
|
402
|
+
You can either tag with "Short" or "short".
|
403
|
+
|
404
|
+
==== +++<u>Num (Numerical)</u>+++
|
405
|
+
You can either tag with "num" or "Num".
|
406
|
+
|
407
|
+
If the tolerance is 1 and the answer is 4, then [3, 5] is an interval for a possible answer.
|
408
|
+
|
409
|
+
If a student writes the correct answer without the correct unit, they will lose half of the marks.
|
410
|
+
|
411
|
+
WARNING: Use coma (,) to separate units, and the dot (.) for decimal.
|
412
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
begin
|
2
|
+
require_relative 'lib/asciidoctor-moodle/version'
|
3
|
+
rescue LoadError
|
4
|
+
require 'asciidoctor-moodle/version'
|
5
|
+
end
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'asciidoctor-moodle'
|
9
|
+
s.version = Asciidoctor::Moodle::VERSION
|
10
|
+
s.summary = 'Converts AsciiDoc documents to Moodle XML'
|
11
|
+
s.description = 'An Asciidoctor converter that converts AsciiDoc to Moodle XML documents'
|
12
|
+
s.authors = ['Gerson Sunyé', 'Robin Gloaguen']
|
13
|
+
s.email = ['gerson.sunye@gmail.com','robin.gloaguen@hotmail.fr']
|
14
|
+
s.homepage = 'https://github.com/'
|
15
|
+
s.license = 'MIT'
|
16
|
+
s.required_ruby_version = '>= 3.0.0'
|
17
|
+
s.metadata = {
|
18
|
+
'bug_tracker_uri' => 'https://github.com/asciidoctor/asciidoctor-docbook45/issues',
|
19
|
+
'changelog_uri' => 'https://github.com/asciidoctor/asciidoctor-docbook45/blob/master/CHANGELOG.adoc',
|
20
|
+
'mailing_list_uri' => 'http://discuss.asciidoctor.org',
|
21
|
+
'source_code_uri' => 'https://github.com/asciidoctor/asciidoctor-docbook45'
|
22
|
+
}
|
23
|
+
|
24
|
+
# NOTE the logic to build the list of files is designed to produce a usable package even when the git command is not available
|
25
|
+
begin
|
26
|
+
files = (result = `git ls-files -z`.split ?\0).empty? ? Dir['**/*'] : result
|
27
|
+
rescue
|
28
|
+
files = Dir['**/*']
|
29
|
+
end
|
30
|
+
s.files = files.grep %r/^(?:lib\/.+|LICENSE|(?:CHANGELOG|README)\.adoc|\.yardopts|#{s.name}\.gemspec)$/
|
31
|
+
s.require_paths = ['lib']
|
32
|
+
|
33
|
+
s.add_runtime_dependency 'asciidoctor', '>= 2.0.0'
|
34
|
+
s.add_development_dependency 'rake', '~> 12.3.0'
|
35
|
+
s.add_development_dependency 'rspec', '~> 3.8.0'
|
36
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require_relative '../extensions'
|
2
|
+
|
3
|
+
|
4
|
+
module Asciidoctor
|
5
|
+
module Question
|
6
|
+
|
7
|
+
class ClozeMCBlockProcessor < Extensions::BaseProcessor
|
8
|
+
|
9
|
+
def process(parent, source, tag)
|
10
|
+
|
11
|
+
docName = parent.attributes['docname']
|
12
|
+
id = tag[:id]
|
13
|
+
size = tag.size
|
14
|
+
answers = Array.new
|
15
|
+
stringSource= Array.new
|
16
|
+
question = Array.new
|
17
|
+
source.lines.each { |line| stringSource.push line}
|
18
|
+
tag.each { |key, val| answers.push val if key.class==Integer && key>2 && key< size-3} #Récupère les réponses en tag
|
19
|
+
|
20
|
+
new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "#{docName}_question_mc_#{id}"}}
|
21
|
+
blocks = Array.new
|
22
|
+
reader = Asciidoctor::Reader.new(stringSource)
|
23
|
+
answers_block = Asciidoctor::Parser.next_block reader, new_parent
|
24
|
+
|
25
|
+
#Get the answers from the reader to put them in the tabular 'blocks'
|
26
|
+
while answers_block != nil
|
27
|
+
blocks.push answers_block
|
28
|
+
answers_block = Asciidoctor::Parser.next_block reader, new_parent
|
29
|
+
end
|
30
|
+
|
31
|
+
for i in 0..(blocks.size-1)
|
32
|
+
if blocks[i].class==Asciidoctor::List #Using list bloc
|
33
|
+
ans=""
|
34
|
+
blocks[i].items.each do |item|
|
35
|
+
ans << item.text
|
36
|
+
ans << "\n"
|
37
|
+
end
|
38
|
+
reader = Asciidoctor::Reader.new(ans)
|
39
|
+
new_block = Asciidoctor::Parser.next_block reader, new_parent
|
40
|
+
new_block.lines = prepare_answer_lines(answers[(i/2)], new_block.content)
|
41
|
+
blocks[i] = new_block
|
42
|
+
else #Using delimitier
|
43
|
+
next if i % 2 == 0 #There is 1 question follow by 1 answer etc...
|
44
|
+
blocks[i].lines = prepare_answer_lines(answers[(i/2)], blocks[i].content)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
blocks = prepare_question_lines(blocks,docName,id)
|
49
|
+
new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "#{docName}_question_#{id}_mc"}}
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
finalstring = ""
|
54
|
+
blocks.each do |bloc|
|
55
|
+
finalstring << bloc.lines.join("\n")
|
56
|
+
end
|
57
|
+
|
58
|
+
reader = Asciidoctor::Reader.new(finalstring)
|
59
|
+
loop do
|
60
|
+
block = Asciidoctor::Parser.next_block reader, new_parent
|
61
|
+
break if block.nil?
|
62
|
+
new_parent.blocks.push block
|
63
|
+
end
|
64
|
+
|
65
|
+
new_parent
|
66
|
+
end
|
67
|
+
|
68
|
+
def prepare_answer_lines(answer, answerBloc)
|
69
|
+
puts answer
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
class MOODLEClozeMCBlockProcessor < ClozeMCBlockProcessor
|
75
|
+
|
76
|
+
def prepare_answer_lines(answer, stringBlock)
|
77
|
+
answer = answer.chomp # erase ending \n
|
78
|
+
preAns = "+++ {1:MCS:"
|
79
|
+
|
80
|
+
postAns = "}+++"
|
81
|
+
|
82
|
+
stringBlock = stringBlock.each_line.map { |line| line.sub(/(^-|^\*) /, "") }.join
|
83
|
+
|
84
|
+
stringBlock = stringBlock.each_line.map do |line|
|
85
|
+
|
86
|
+
line = line.chomp
|
87
|
+
if line == answer
|
88
|
+
"~=#{line}"
|
89
|
+
else
|
90
|
+
"~#{line}"
|
91
|
+
end
|
92
|
+
end.join(" ")
|
93
|
+
|
94
|
+
stringBlock.slice!(0)
|
95
|
+
stringBlock = "#{preAns}#{stringBlock}#{postAns}"
|
96
|
+
[stringBlock]
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def prepare_question_lines(blocks, docName,id)
|
102
|
+
|
103
|
+
preQuest = " <question type=\"cloze\">
|
104
|
+
<name>
|
105
|
+
<text> #{docName}_question_#{id}_clozemc </text>
|
106
|
+
</name>
|
107
|
+
<questiontext format=\"html\">
|
108
|
+
<text><![CDATA[<p>"
|
109
|
+
postQuest = " </p>]]></text>
|
110
|
+
</questiontext>
|
111
|
+
<generalfeedback format=\"html\">
|
112
|
+
<text></text>
|
113
|
+
</generalfeedback>
|
114
|
+
<penalty>0.3333333</penalty>
|
115
|
+
<hidden>0</hidden>
|
116
|
+
<idnumber></idnumber>
|
117
|
+
</question>"
|
118
|
+
size = (blocks.size) -1
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
blocks[0].lines.prepend("+++")
|
123
|
+
blocks[0].lines.prepend(preQuest)
|
124
|
+
blocks[0].lines.prepend("+++")
|
125
|
+
|
126
|
+
blocks[size].lines.push("+++")
|
127
|
+
blocks[size].lines.push(postQuest)
|
128
|
+
blocks[size].lines.push("+++")
|
129
|
+
|
130
|
+
blocks
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|