asciidoctor-question 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 01e688b1fd4efa2544898b54ec6f3fc78e855456
4
+ data.tar.gz: 697269794fcf44fbf1e8481eded01fd4ef647b28
5
+ SHA512:
6
+ metadata.gz: ffcdf42dcb9d4ab87324ae6b00abba115d76dcae6c6cf08a0c16ba978c5bb74bbaf087911bc0b10e6d9593b30ae4d287ae2e3ac62c8c41198600b94f1837ceb7
7
+ data.tar.gz: 8b60dc0d1c785cacc700f70e72badde086983c68c093a21769a0e8654c32e9a50f0c288b4235bcbb602ec2a4afb3d1b9e0294e91986021b7a59a016ff7f87f5d
data/CHANGELOG.adoc ADDED
@@ -0,0 +1,35 @@
1
+ = Asciidoctor-question Changelog
2
+
3
+ == Development
4
+
5
+ == 0.4
6
+
7
+ Enhancements::
8
+ * add attribute :solution: for PDF generation - this generates a PDF with the solutions to the questions
9
+
10
+ == 0.3
11
+
12
+ Enhancements::
13
+
14
+ * add README.adoc
15
+ * add LICENSE.adoc
16
+ * add CHANGELOG.adoc
17
+ * add reset button to every question
18
+
19
+ Bug Fixes::
20
+
21
+ * add the macro substitution to source blocks, if it is in a gap text question
22
+ * make the mc correct or incorrect icons smaller
23
+ * mc correct and incorrect icons not working in firefox
24
+
25
+ == 0.2
26
+
27
+ Enhancements::
28
+
29
+ * add support for the `question` block with gap type
30
+
31
+ == 0.1
32
+
33
+ Initial release::
34
+
35
+ * Provides Asciidoctor extension for `question` blocks with a mc type
data/LICENSE.adoc ADDED
@@ -0,0 +1,22 @@
1
+ .The MIT License (MIT)
2
+ ....
3
+ Copyright (c) 2016 Marcel Hoppe and Technische Hochschule Mittelhessen - University of Applied Sciences
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+ ....
data/README.adoc ADDED
@@ -0,0 +1,130 @@
1
+ = Asciidoctor Question
2
+ Marcel Hoppe <marcel.hoppe@mni.thm.de>
3
+ :description: README for the Asciidoctor Question extension for Asciidoctor.
4
+ :version: 0.4
5
+
6
+ ifdef::env-github[:toc: macro]
7
+ ifndef::env-site[:toc: preamble]
8
+ ifndef::imagesdir[:imagesdir: images]
9
+ :icons: font
10
+ :source-highlighter: coderay
11
+ :source-language: asciidoc
12
+ :table-caption!:
13
+ :example-caption!:
14
+ :figure-caption!:
15
+ :check: icon:check[]
16
+ ifdef::env-github[:check: :ballot_box_with_check:]
17
+ ifndef::env-site[:status:]
18
+ :uri-asciidoctor-api: http://asciidoctor.org/docs/user-manual/#api
19
+ :uri-asciidoctor-extensions: http://asciidoctor.org/docs/user-manual/#extension-points
20
+
21
+ image:https://img.shields.io/gem/v/asciidoctor-question.svg?label=gem%20version[Gem Version, link=https://rubygems.org/gems/asciidoctor-question]
22
+ image:https://img.shields.io/badge/license-MIT-blue.svg[MIT License, link=#copyright]
23
+
24
+ Asciidoctor Question is a set of Asciidoctor extensions that allows you to add questions as multiple choice and gap text. The questions are defined using plain text in your AsciiDoc document.
25
+
26
+ ifeval::["{toc-placement}" == "macro"]
27
+ [discrete]
28
+ == Contents
29
+
30
+ toc::[title={blank}]
31
+ endif::[]
32
+
33
+ == Installation
34
+
35
+ There are two options to install Asciidoctor Question. First using `gem install` on the CLI:
36
+
37
+ $ gem install asciidoctor-question
38
+
39
+ or by adding the following entry to your project's [.path]_Gemfile_.
40
+
41
+ .Gemfile
42
+ [source,ruby,subs="verbatim,attributes"]
43
+ ----
44
+ gem 'asciidoctor-question', '~> {version}'
45
+ ----
46
+
47
+ and execute `bundle` in the CLI.
48
+
49
+ $ bundle
50
+
51
+ == Creating a Question
52
+
53
+ A question is written inside a literal block, which needs two attributes.
54
+
55
+ .Anatomy of a question
56
+ ----
57
+ [question, question-type] // <1> <2>
58
+ .... // <3>
59
+ Question in appropriate syntax
60
+ ....
61
+ ----
62
+ <1> The first positional attribute in the attribute list specifies that this block is a question.
63
+ <2> The second positional attribute defines the type of this question (mc or gap)
64
+ <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.
65
+
66
+ The following question types are available:
67
+
68
+ [cols="2,3a,3a",options="header"]
69
+ |===
70
+ |Question Type
71
+ |input
72
+ |output
73
+
74
+ |mc
75
+ |
76
+ [source]
77
+ ----
78
+ [question, mc]
79
+ ....
80
+ Lorem ipsum dolor sit amet, consetetur
81
+ sadipscing elitr, sed diam nonumy eirmod
82
+ tempor invidunt ut labore et dolore
83
+ magna aliquyam erat, sed diam voluptua.
84
+
85
+ - [X] ipsum
86
+ - [ ] eltir
87
+ - [X] ut
88
+ ....
89
+ ----
90
+ |
91
+
92
+ image::mc.png[]
93
+
94
+ |gap
95
+ |
96
+ [source]
97
+ ----
98
+ [question, gap]
99
+ ....
100
+ At vero eos et __accusam__ et justo
101
+ duo dolores et ea rebum. Stet clita
102
+ kasd gubergren, no sea __takimata
103
+ sanctus est Lorem__ ipsum dolor sit
104
+ amet. Lorem __ipsum dolor sit amet__,
105
+ consetetur sadipscing elitr, sed diam
106
+ nonumy __eirmod tempor invidunt__ ut
107
+ labore et dolore magna aliquyam erat,
108
+ sed diam voluptua.
109
+ ....
110
+ ----
111
+ |
112
+ image::gap.png[]
113
+ |===
114
+
115
+
116
+ == Generating a Question Document from a Terminal
117
+
118
+ You can load Asciidoctor question in a terminal using the `-r` flag.
119
+
120
+ $ asciidoctor -r asciidoctor-question sample.adoc
121
+
122
+ You can also use Asciidoctor question with other converters, such as Asciidoctor PDF.
123
+ Asciidoctor-pdf is also loaded with the `-r` flag.
124
+
125
+ $ asciidoctor -r asciidoctor-question -r asciidoctor-pdf -b pdf sample.adoc
126
+
127
+ Or, you can invoke Asciidoctor and the PDF converter with the `asciidoctor-pdf` command.
128
+ The command implicitly sets the `-r` and `-b` flags for PDF output.
129
+
130
+ $ asciidoctor-pdf -r asciidoctor-question sample.adoc
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/images/gap.png ADDED
Binary file
data/images/mc.png ADDED
Binary file
@@ -0,0 +1,40 @@
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]', '====', 'Fehler! ' + 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
+ id = tag[:id]
30
+ parent.blocks.push Asciidoctor::Block.new parent, :pass, :source => "
31
+ <p style=\"margin-bottom: 25px\">
32
+ <button onclick='resolve(#{id})'>resolve</button>
33
+ <button onclick='reset(#{id})'>reset</button>
34
+ </p>"
35
+ parent
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,72 @@
1
+ require_relative '../extensions'
2
+
3
+ module Asciidoctor
4
+ module Question
5
+
6
+ class GAPBlockProcessor < Extensions::BaseProcessor
7
+
8
+ def process(parent, source, tag)
9
+ id = tag[:id]
10
+ err = nil
11
+
12
+ question = source.lines
13
+
14
+ question.map! do |line|
15
+ line.gsub /__([^_]+?)__/ do |value|
16
+ prepare_gap value.gsub('_', ''), tag
17
+ end
18
+ end
19
+
20
+ new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "question_gap_#{id}"}}
21
+
22
+ reader = Asciidoctor::Reader.new question
23
+
24
+ loop do
25
+ block = Asciidoctor::Parser.next_block reader, new_parent
26
+ break if block.nil?
27
+
28
+ if block.context == :listing
29
+ block.subs.push :macros
30
+ block.subs.push :quotes
31
+ end
32
+ new_parent.blocks.push block
33
+ end
34
+
35
+ if err.nil?
36
+ post_answers new_parent, tag
37
+ else
38
+ process_error_push new_parent, err, source.lines
39
+ end
40
+
41
+ new_parent
42
+ end
43
+
44
+ def prepare_gap(value, tag)
45
+ value
46
+ end
47
+ end
48
+
49
+ class PDFGAPBlockProcessor < GAPBlockProcessor
50
+ def prepare_gap(value, tag)
51
+ if tag[:solution] then
52
+ "`[red]## +++__#{value}__+++ ##`"
53
+ else
54
+ "+++ #{'_' * (value.size + 4)} +++"
55
+ end
56
+
57
+ end
58
+
59
+ def post_answers(parent, tag)
60
+
61
+ end
62
+
63
+ end
64
+
65
+ class HTMLGAPBlockProcessor < GAPBlockProcessor
66
+
67
+ def prepare_gap(value, tag)
68
+ '+++<gap> <input type="text"/> <answer class="hidden">' + value + '</answer> </gap>+++'
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,106 @@
1
+ require_relative '../extensions'
2
+
3
+ module Asciidoctor
4
+ module Question
5
+
6
+ class MultipleChoiceBlockProcessor < Extensions::BaseProcessor
7
+
8
+ name_positional_attributes :shuffle
9
+
10
+ def process(parent, source, tag)
11
+ id = tag[:id]
12
+ err = nil
13
+ question = Array.new
14
+ answers = Array.new ['[options=interactive]']
15
+ switch = false
16
+
17
+ source.lines.each do |line|
18
+ switch = true if line =~ /^-\s?\[/
19
+ if switch
20
+ answers.push line
21
+ else
22
+ question.push line
23
+ end
24
+ end
25
+
26
+ answers = prepare_answer_lines answers
27
+
28
+ new_parent = Asciidoctor::Block.new parent, :open, {:attributes => {'id' => "question_mc_#{id}"}}
29
+
30
+ reader = Asciidoctor::Reader.new(question)
31
+ loop do
32
+ block = Asciidoctor::Parser.next_block reader, new_parent
33
+ break if block.nil?
34
+ new_parent.blocks.push block
35
+ end
36
+
37
+ reader = Asciidoctor::Reader.new(answers)
38
+ answers_block = Asciidoctor::Parser.next_block reader, new_parent
39
+ if answers_block.nil?
40
+ err = 'Es sind keine Antworten vorhanden!'
41
+ end
42
+
43
+ if err.nil?
44
+ new_parent.blocks.push prepare_answers answers_block, tag
45
+ post_answers new_parent, tag
46
+
47
+ else
48
+ process_error_push new_parent, err, answers
49
+ end
50
+ new_parent
51
+ end
52
+
53
+ def prepare_answer_lines(lines)
54
+ lines
55
+ end
56
+
57
+ def prepare_answers(answers_block, tag)
58
+ answers_block.blocks.shuffle! if tag[:shuffle] == 'shuffle'
59
+ answers_block
60
+ end
61
+
62
+ end
63
+
64
+ class PDFMultipleChoiceBlockProcessor < MultipleChoiceBlockProcessor
65
+ def prepare_answers(answers_block, tag)
66
+ super
67
+ unless tag[:solution]
68
+ answers_block.blocks.each do |answer|
69
+ answer.attributes.delete('checked')
70
+ end
71
+ end
72
+ answers_block
73
+ end
74
+
75
+ def post_answers(parent, tag)
76
+
77
+ end
78
+ end
79
+
80
+ class HTMLMultipleChoiceBlockProcessor < MultipleChoiceBlockProcessor
81
+
82
+ def prepare_answer_lines(lines)
83
+ lines.map! do |answer|
84
+ if answer =~ /^-\s?\[/ then
85
+ answer.sub ']', '] +++ <span/> +++'
86
+ else
87
+ answer
88
+ end
89
+ end
90
+ lines
91
+ end
92
+
93
+ def prepare_answers(answers_block, tag)
94
+ super
95
+ id = tag[:id]
96
+ aid = -1
97
+ answers_block.attributes['id'] = "answers_mc_#{id}"
98
+
99
+ answers_block.blocks.each do |answer|
100
+ answer.attributes['id'] = "answer_mc_#{id}_#{aid += 1}"
101
+ end
102
+ answers_block
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,70 @@
1
+
2
+ require_relative '../extensions'
3
+ require_relative '../multiple_choice/extension'
4
+ require_relative '../gap/extension'
5
+ require_relative './post_processor'
6
+
7
+ module Asciidoctor
8
+ module Question
9
+ class QuestionBlockProcessor < Extensions::BaseProcessor
10
+ name_positional_attributes [:type, :shuffle]
11
+
12
+ def initialize name = nil, config = {}
13
+ super name, config
14
+ @id = 0
15
+ end
16
+
17
+ def process(parent, source, tag)
18
+ block = nil
19
+ err = nil
20
+
21
+ type = tag[:type]
22
+ tag[:id] = @id = @id + 1
23
+
24
+ tag[:solution] = !parent.attributes['solution'].nil?
25
+
26
+ if type.nil?
27
+ err = 'Typ fehlt.'
28
+ end
29
+
30
+ if err.nil?
31
+ if type == 'mc' or type == 'multiplechoice' or type == 'multiple_choice'
32
+ block = process_question_mc parent, source, tag
33
+ elsif type == 'gap'
34
+ block = process_question_gap parent, source, tag
35
+ end
36
+ else
37
+ block = process_error parent, err, source.lines
38
+ end
39
+
40
+ block
41
+ end
42
+ end
43
+
44
+
45
+ class HTMLQuestionBlockProcessor < QuestionBlockProcessor
46
+ name_positional_attributes [:type, :shuffle]
47
+
48
+ def process_question_mc parent, source, tag
49
+ HTMLMultipleChoiceBlockProcessor.new.process parent, source, tag
50
+ end
51
+
52
+ def process_question_gap parent, source, tag
53
+ HTMLGAPBlockProcessor.new.process parent, source, tag
54
+ end
55
+ end
56
+
57
+
58
+ class PDFQuestionBlockProcessor < QuestionBlockProcessor
59
+ name_positional_attributes [:type, :shuffle]
60
+
61
+ def process_question_mc parent, source, tag
62
+ PDFMultipleChoiceBlockProcessor.new.process parent, source, tag
63
+ end
64
+
65
+ def process_question_gap parent, source, tag
66
+ PDFGAPBlockProcessor.new.process parent, source, tag
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,41 @@
1
+ require 'nokogiri'
2
+
3
+ module Asciidoctor
4
+ module Question
5
+ class HTMLPostProcessor < Asciidoctor::Extensions::Postprocessor
6
+ def process(document, output)
7
+ doc = Nokogiri::HTML(output)
8
+ head = doc.at_css 'head'
9
+ basedir = File.expand_path('../../../../', __FILE__)
10
+ file = File.open("#{basedir}/res/asciidoctor-question/question.css")
11
+ head.add_child("
12
+ <style id=\"question\">
13
+ #{file.read}
14
+ </style>
15
+ ")
16
+ file.close
17
+
18
+ file = File.open("#{basedir}/res/asciidoctor-question/question.js")
19
+ head.add_child("<script type=\"text/javascript\">
20
+ #{file.read}
21
+ </script>")
22
+ file.close
23
+
24
+ questions = doc.css 'div[id*=question]'
25
+ questions.each do |question|
26
+ id = question['id']
27
+ parts = id.split '_'
28
+ question['id'] = "#{parts[0]}_#{parts[2]}"
29
+ question['data-type'] = parts[1]
30
+ end
31
+
32
+ answers = doc.css 'div[id*=question][data-type=mc] input[type="checkbox"]'
33
+ answers.each do |answer|
34
+ answer['data-correct'] = answer.key?('checked')
35
+ answer.delete('checked')
36
+ end
37
+ doc.to_html
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'extensions'
2
+
3
+ Asciidoctor::Extensions.register do
4
+ require_relative 'question/extension'
5
+
6
+ if document.basebackend? 'html' and not document.backend == 'pdf'
7
+ block Asciidoctor::Question::HTMLQuestionBlockProcessor, :question
8
+ postprocessor Asciidoctor::Question::HTMLPostProcessor
9
+ end
10
+
11
+ block Asciidoctor::Question::PDFQuestionBlockProcessor, :question if document.backend == 'pdf'
12
+ end
@@ -0,0 +1,5 @@
1
+ module Asciidoctor
2
+ module Question
3
+ VERSION = "0.4.1"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require_relative 'asciidoctor-question/question'
@@ -0,0 +1,28 @@
1
+ .hidden {
2
+ display: none;
3
+ }
4
+
5
+ div[id*=question][data-type=gap] gap > input.incorrect {
6
+ font-weight: bold;
7
+ color: red;
8
+ }
9
+
10
+
11
+ div[id*=question][data-type=gap] gap > answer, div[id*=question][data-type=gap] gap > input.correct {
12
+ font-weight: bold;
13
+ color: green;
14
+ }
15
+
16
+ div[id*=question][data-type=mc] input[type="checkbox"].show ~ span::before {
17
+ display: inline;
18
+ width: 16px;
19
+ height: 16px;
20
+ }
21
+
22
+ div[id*=question][data-type=mc] input[type="checkbox"][data-correct="true"].show ~ span::before {
23
+ content: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxNnB4IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2cHgiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxwYXRoIGZpbGw9Im9saXZlZHJhYiIgc3Ryb2tlPSJvbGl2ZWRyYWIiIGQ9Ik0yMS42NTIsMy4yMTFjLTAuMjkzLTAuMjk1LTAuNzctMC4yOTUtMS4wNjEsMEw5LjQxLDE0LjM0ICBjLTAuMjkzLDAuMjk3LTAuNzcxLDAuMjk3LTEuMDYyLDBMMy40NDksOS4zNTFDMy4zMDQsOS4yMDMsMy4xMTQsOS4xMywyLjkyMyw5LjEyOUMyLjczLDkuMTI4LDIuNTM0LDkuMjAxLDIuMzg3LDkuMzUxICBsLTIuMTY1LDEuOTQ2QzAuMDc4LDExLjQ0NSwwLDExLjYzLDAsMTEuODIzYzAsMC4xOTQsMC4wNzgsMC4zOTcsMC4yMjMsMC41NDRsNC45NCw1LjE4NGMwLjI5MiwwLjI5NiwwLjc3MSwwLjc3NiwxLjA2MiwxLjA3ICBsMi4xMjQsMi4xNDFjMC4yOTIsMC4yOTMsMC43NjksMC4yOTMsMS4wNjIsMGwxNC4zNjYtMTQuMzRjMC4yOTMtMC4yOTQsMC4yOTMtMC43NzcsMC0xLjA3MUwyMS42NTIsMy4yMTF6Ii8+PC9zdmc+);
24
+ }
25
+
26
+ div[id*=question][data-type=mc] input[type="checkbox"][data-correct="false"].show ~ span::before {
27
+ content: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxNnB4IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2cHgiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxwYXRoIGZpbGw9Im1hcm9vbiIgc3Ryb2tlPSJtYXJvb24iIGQ9Ik0yMi4yNDUsNC4wMTVjMC4zMTMsMC4zMTMsMC4zMTMsMC44MjYsMCwxLjEzOWwtNi4yNzYsNi4yN2MtMC4zMTMsMC4zMTItMC4zMTMsMC44MjYsMCwxLjE0bDYuMjczLDYuMjcyICBjMC4zMTMsMC4zMTMsMC4zMTMsMC44MjYsMCwxLjE0bC0yLjI4NSwyLjI3N2MtMC4zMTQsMC4zMTItMC44MjgsMC4zMTItMS4xNDIsMGwtNi4yNzEtNi4yNzFjLTAuMzEzLTAuMzEzLTAuODI4LTAuMzEzLTEuMTQxLDAgIGwtNi4yNzYsNi4yNjdjLTAuMzEzLDAuMzEzLTAuODI4LDAuMzEzLTEuMTQxLDBsLTIuMjgyLTIuMjhjLTAuMzEzLTAuMzEzLTAuMzEzLTAuODI2LDAtMS4xNGw2LjI3OC02LjI2OSAgYzAuMzEzLTAuMzEyLDAuMzEzLTAuODI2LDAtMS4xNEwxLjcwOSw1LjE0N2MtMC4zMTQtMC4zMTMtMC4zMTQtMC44MjcsMC0xLjE0bDIuMjg0LTIuMjc4QzQuMzA4LDEuNDE3LDQuODIxLDEuNDE3LDUuMTM1LDEuNzMgIEwxMS40MDUsOGMwLjMxNCwwLjMxNCwwLjgyOCwwLjMxNCwxLjE0MSwwLjAwMWw2LjI3Ni02LjI2N2MwLjMxMi0wLjMxMiwwLjgyNi0wLjMxMiwxLjE0MSwwTDIyLjI0NSw0LjAxNXoiLz48L3N2Zz4=);
28
+ }
@@ -0,0 +1,53 @@
1
+ function resolve(questionId) {
2
+ var q = document.getElementById("question_" + questionId)
3
+ var type = q.getAttribute("data-type")
4
+ var elems
5
+ var pos
6
+ var answer
7
+
8
+ if(type == "mc") {
9
+ elems = q.getElementsByTagName("input")
10
+ for(pos = 0; pos < elems.length; pos++) {
11
+ answer = elems[pos]
12
+ answer.setAttribute("class", "show")
13
+ }
14
+ } else if(type == "gap") {
15
+ elems = q.getElementsByTagName("gap")
16
+ for(pos = 0; pos < elems.length; pos++) {
17
+ var gap = elems[pos]
18
+ var input = gap.getElementsByTagName("input")[0]
19
+ answer = gap.getElementsByTagName("answer")[0]
20
+ if(input.value == answer.textContent) {
21
+ input.setAttribute("class", "correct")
22
+ } else {
23
+ input.setAttribute("class", "incorrect")
24
+ answer.setAttribute("class", "")
25
+ }
26
+ }
27
+ }
28
+ }
29
+
30
+ function reset(questionId) {
31
+ var q = document.getElementById("question_" + questionId)
32
+ var type = q.getAttribute("data-type")
33
+ var elems
34
+ var pos
35
+ var answer
36
+
37
+ if(type == "mc") {
38
+ elems = q.getElementsByTagName("input")
39
+ for(pos = 0; pos < elems.length; pos++) {
40
+ answer = elems[pos]
41
+ answer.setAttribute("class", "")
42
+ }
43
+ } else if(type == "gap") {
44
+ elems = q.getElementsByTagName("gap")
45
+ for(pos = 0; pos < elems.length; pos++) {
46
+ var gap = elems[pos]
47
+ var input = gap.getElementsByTagName("input")[0]
48
+ answer = gap.getElementsByTagName("answer")[0]
49
+ input.setAttribute("class", "")
50
+ answer.setAttribute("class", "hidden")
51
+ }
52
+ }
53
+ }
data/test/test.adoc ADDED
@@ -0,0 +1,54 @@
1
+
2
+ [question, gap]
3
+ ====
4
+ Lorem __ipsum__ dolor sit amet, consetetur __sadipscing__ elitr,
5
+ sed diam nonumy eirmod __tempor invidunt ut__ labore et dolore
6
+ magna aliquyam erat, sed diam voluptua. At vero eos et
7
+ accusam et justo duo dolores et ea rebum.
8
+
9
+ [source,ruby]
10
+ ----
11
+ Stet clita kasd gubergren, no sea takimata __sanctus__ est Lorem ipsum dolor sit amet.
12
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
13
+ sed diam nonumy eirmod tempor __invidunt__ ut labore et
14
+ dolore magna aliquyam erat, sed diam voluptua.
15
+ ----
16
+
17
+ At vero eos et __accusam__ et justo duo dolores et ea rebum.
18
+ Stet clita kasd gubergren, no sea takimata __sanctus__ est Lorem ipsum dolor sit amet.
19
+ ====
20
+
21
+ [question, mc]
22
+ ====
23
+ Das hier ist eine Frage:
24
+ ----
25
+ test
26
+ ----
27
+
28
+ - [ ] Hallo 1234
29
+ pkfsepgkdsjghü ojsoip jhsotjhotsjoh std oh sodn hodnh adinhididnhdtd dp dknwodh snmhd öndpishdod mdhopj
30
+ - [*] test
31
+ ====
32
+
33
+ [question, mc]
34
+ ....
35
+ ====
36
+ test
37
+ ====
38
+
39
+ - [ ] Hallo 1234
40
+ pkfsepgkdsjghü ojsoip jhsotjhotsjoh std oh sodn hodnh adinhididnhdtd dp dknwodh snmhd öndpishdod mdhopj
41
+ - [*] test
42
+ ....
43
+
44
+ [question, mc]
45
+ --
46
+ Das hier ist eine Frage:
47
+ ====
48
+ test
49
+ ====
50
+
51
+ - [ ] Hallo 1234
52
+ pkfsepgkdsjghü ojsoip jhsotjhotsjoh std oh sodn hodnh adinhididnhdtd dp dknwodh snmhd öndpishdod mdhopj
53
+ - [*] test
54
+ --
data/test/test.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'asciidoctor-pdf'
2
+ require_relative '../lib/asciidoctor-question'
3
+
4
+ #Asciidoctor.convert_file 'test/test.adoc', {:safe => :safe, :solution => ''}
5
+ Asciidoctor.convert_file 'test/test.adoc', {:safe => :safe, :backend => 'pdf'}
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asciidoctor-question
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.1
5
+ platform: ruby
6
+ authors:
7
+ - Marcel Hoppe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: asciidoctor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.6'
83
+ description: Asciidoctor questioning extension.rb
84
+ email:
85
+ - marcel.hoppe@mni.thm.de
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.adoc
91
+ - LICENSE.adoc
92
+ - README.adoc
93
+ - Rakefile
94
+ - images/gap.png
95
+ - images/mc.png
96
+ - lib/asciidoctor-question.rb
97
+ - lib/asciidoctor-question/extensions.rb
98
+ - lib/asciidoctor-question/gap/extension.rb
99
+ - lib/asciidoctor-question/multiple_choice/extension.rb
100
+ - lib/asciidoctor-question/question.rb
101
+ - lib/asciidoctor-question/question/extension.rb
102
+ - lib/asciidoctor-question/question/post_processor.rb
103
+ - lib/asciidoctor-question/version.rb
104
+ - res/asciidoctor-question/question.css
105
+ - res/asciidoctor-question/question.js
106
+ - test/test.adoc
107
+ - test/test.rb
108
+ homepage: https://github.com/hobbypunk90/asciidoctor-question
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '2.3'
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '2'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.6.8
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: An extension.rb for asciidoctor-question that adds support for multiple choice
135
+ and gap questions
136
+ test_files:
137
+ - test/test.adoc
138
+ - test/test.rb