asciidoctor-question 0.4.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.
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