asker-tool 2.5.7 → 2.5.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -15
- data/lib/asker/check_input/check_haml_data.rb +7 -2
- data/lib/asker/check_input.rb +0 -2
- data/lib/asker/data/concept.rb +14 -38
- data/lib/asker/loader/content_loader.rb +14 -15
- data/lib/asker/loader/directory_loader.rb +2 -10
- data/lib/asker/loader/embedded_file.rb +2 -3
- data/lib/asker/loader/file_loader.rb +5 -5
- data/lib/asker/loader/haml_loader.rb +1 -1
- data/lib/asker/loader/input_loader.rb +0 -4
- data/lib/asker/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 211d45e28562281dbadb99c156ae2e630d28bae27d4314f74771c7637de889b7
|
4
|
+
data.tar.gz: 16625618a4b4a26753727abbe6f1c59e51bd63eb99573fd929a3d98b06cdcd39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2ac75d61319e1c833d72dc8224da00df81f57636fa5f1f61e887cc5ddff47a98bd6f2e389de58c142c77c224ea1dd87ad3971479c50b1024a691626bae13a8e
|
7
|
+
data.tar.gz: 34aa413ffac40f922b18ec07ecefec8fe7d2132bd2f20f3929ae87f7666958adefd75cc3bd6c67c12078f004a1ce61e743837a46e55c78c85a454e13d073e184
|
data/README.md
CHANGED
@@ -5,16 +5,13 @@
|
|
5
5
|
|
6
6
|
Generate a lot of questions from an _input_ text file with on your own _definitions_. In a way, this _input file_ is a concept map.
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
ASKER helps trainers to create a huge amount of questions, from a definitions (_conceptual entities_) input file.
|
8
|
+
Asker helps trainers to create a huge amount of questions, from a definitions (_conceptual entities_) input file.
|
11
9
|
|
12
|
-
|
13
|
-
* Multiplatform.
|
10
|
+
![logo](./docs/images/logo.png)
|
14
11
|
|
15
|
-
|
12
|
+
# Installation
|
16
13
|
|
17
|
-
|
14
|
+
At first install Ruby and then:
|
18
15
|
|
19
16
|
```
|
20
17
|
gem install asker-tool
|
@@ -22,12 +19,17 @@ gem install asker-tool
|
|
22
19
|
|
23
20
|
> REMEMBER: Update Asker with `gem update asker-tool`
|
24
21
|
|
25
|
-
|
22
|
+
# Usage
|
26
23
|
|
27
|
-
|
28
|
-
|
24
|
+
| Step | Action | Description |
|
25
|
+
| ---: | --------------------- | ----------- |
|
26
|
+
| 1 | Create your **input file** | Create input file with your contents (_conceptual map_). Here are some [examples](./docs/examples). And more examples at this [repository](https://github.com/dvarrui/asker-inputs).
|
27
|
+
| 2 | **Run `asker`** | `asker PATH/TO/INPUT` |
|
28
|
+
| 3 | Choose your **output files** | Output files saved into the `output` folder |
|
29
29
|
|
30
|
-
|
30
|
+
Let's see an example creating questions from ACDC input example file:
|
31
|
+
|
32
|
+
```console
|
31
33
|
❯ asker docs/examples/bands/acdc.haml
|
32
34
|
|
33
35
|
+--------------------+-----------+---------+---------+---+---+----+---+---+----+
|
@@ -40,11 +42,12 @@ gem install asker-tool
|
|
40
42
|
+--------------------+-----------+---------+---------+---+---+----+---+---+----+
|
41
43
|
```
|
42
44
|
|
43
|
-
|
45
|
+
# Features
|
44
46
|
|
45
|
-
|
47
|
+
* [Free Software License](LICENSE).
|
48
|
+
* Multiplatform.
|
46
49
|
|
47
|
-
|
50
|
+
# Documentation
|
48
51
|
|
49
52
|
* [Installation](docs/install/README.md)
|
50
53
|
* [Videos](docs/videos.md)
|
@@ -55,6 +58,15 @@ gem install asker-tool
|
|
55
58
|
* [Problem to solve](docs/idea.md)
|
56
59
|
* [History](docs/history.md)
|
57
60
|
|
58
|
-
|
61
|
+
# Contact
|
59
62
|
|
60
63
|
* **Email**: `teuton.software@protonmail.com`
|
64
|
+
|
65
|
+
# Contributing
|
66
|
+
|
67
|
+
1. Make sure you have Ruby installed
|
68
|
+
1. Fork it
|
69
|
+
1. Create your feature branch (`git checkout -b my-new-feature`)
|
70
|
+
1. Commit your changes (`git commit -am 'Add some feature'`)
|
71
|
+
1. Push to the branch (`git push origin my-new-feature`)
|
72
|
+
1. Create new Pull Request.
|
@@ -32,7 +32,6 @@ class CheckHamlData
|
|
32
32
|
|
33
33
|
def show_errors
|
34
34
|
errors = 0
|
35
|
-
# puts "Line : Error description"
|
36
35
|
puts "\n"
|
37
36
|
@outputs.each do |i|
|
38
37
|
next if i[:state] == :ok
|
@@ -164,9 +163,15 @@ class CheckHamlData
|
|
164
163
|
if find_parent(index) != :concept
|
165
164
|
@outputs[index][:state] = :err
|
166
165
|
@outputs[index][:msg] = 'Parent(concept) not found!'
|
167
|
-
elsif !line.match(/^\s\s\s\s%def\s/)
|
166
|
+
elsif !line.match(/^\s\s\s\s%def[\s{]/)
|
168
167
|
@outputs[index][:state] = :err
|
169
168
|
@outputs[index][:msg] = 'Write 4 spaces before %def'
|
169
|
+
else
|
170
|
+
items = line.strip.split
|
171
|
+
if items.size < 2
|
172
|
+
@outputs[index][:state] = :err
|
173
|
+
@outputs[index][:msg] = '%def has no definition'
|
174
|
+
end
|
170
175
|
end
|
171
176
|
end
|
172
177
|
|
data/lib/asker/check_input.rb
CHANGED
data/lib/asker/data/concept.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'rainbow'
|
4
2
|
require 'rexml/document'
|
5
3
|
|
@@ -8,10 +6,6 @@ require_relative '../loader/embedded_file'
|
|
8
6
|
require_relative 'table'
|
9
7
|
require_relative 'data_field'
|
10
8
|
|
11
|
-
##
|
12
|
-
# Store Concept information
|
13
|
-
# rubocop:disable Metrics/ClassLength
|
14
|
-
# rubocop:disable Style/ClassVars
|
15
9
|
class Concept
|
16
10
|
attr_reader :id # Unique identifer (Integer)
|
17
11
|
attr_reader :lang # Lang code (By default is the same as map lang)
|
@@ -30,8 +24,6 @@ class Concept
|
|
30
24
|
# @param filename (String)
|
31
25
|
# @param lang_code (String)
|
32
26
|
# @param context (Array)
|
33
|
-
# rubocop:disable Metrics/MethodLength
|
34
|
-
# rubocop:disable Metrics/AbcSize
|
35
27
|
def initialize(xml_data, filename, lang_code = 'en', context = [])
|
36
28
|
@@id += 1
|
37
29
|
@id = @@id
|
@@ -62,8 +54,6 @@ class Concept
|
|
62
54
|
|
63
55
|
read_data_from_xml(xml_data)
|
64
56
|
end
|
65
|
-
# rubocop:enable Metrics/MethodLength
|
66
|
-
# rubocop:enable Metrics/AbcSize
|
67
57
|
|
68
58
|
def name(option = :raw)
|
69
59
|
DataField.new(@names[0], @id, @type).get(option)
|
@@ -87,12 +77,9 @@ class Concept
|
|
87
77
|
@data[:neighbors].reverse!
|
88
78
|
end
|
89
79
|
|
90
|
-
# rubocop:disable Metrics/MethodLength
|
91
|
-
# rubocop:disable Metrics/AbcSize
|
92
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
93
80
|
def calculate_nearness_to_concept(other)
|
94
81
|
a = ProjectData.instance.get(:weights)
|
95
|
-
#Application.instance.config['ai']['formula_weights']
|
82
|
+
# Application.instance.config['ai']['formula_weights']
|
96
83
|
weights = a.split(',').map(&:to_f)
|
97
84
|
|
98
85
|
max1 = @context.count
|
@@ -110,12 +97,7 @@ class Concept
|
|
110
97
|
max = (max1 * weights[0] + max2 * weights[1] + max3 * weights[2])
|
111
98
|
(alike * 100.0 / max)
|
112
99
|
end
|
113
|
-
# rubocop:enable Metrics/MethodLength
|
114
|
-
# rubocop:enable Metrics/AbcSize
|
115
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
116
100
|
|
117
|
-
# rubocop:disable Metrics/MethodLength
|
118
|
-
# rubocop:disable Metrics/AbcSize
|
119
101
|
def try_adding_references(other)
|
120
102
|
reference_to = 0
|
121
103
|
@data[:tags].each do |i|
|
@@ -132,8 +114,6 @@ class Concept
|
|
132
114
|
@data[:reference_to] << other.name
|
133
115
|
other.data[:referenced_by] << name
|
134
116
|
end
|
135
|
-
# rubocop:enable Metrics/MethodLength
|
136
|
-
# rubocop:enable Metrics/AbcSize
|
137
117
|
|
138
118
|
def tags
|
139
119
|
@data[:tags]
|
@@ -165,17 +145,16 @@ class Concept
|
|
165
145
|
|
166
146
|
private
|
167
147
|
|
168
|
-
# rubocop:disable Metrics/MethodLength
|
169
148
|
def read_data_from_xml(xml_data)
|
170
149
|
xml_data.elements.each do |i|
|
171
150
|
case i.name
|
172
|
-
when
|
151
|
+
when "names"
|
173
152
|
process_names(i)
|
174
|
-
when
|
153
|
+
when "tags"
|
175
154
|
process_tags(i)
|
176
|
-
when
|
155
|
+
when "def"
|
177
156
|
process_def(i)
|
178
|
-
when
|
157
|
+
when "table"
|
179
158
|
@data[:tables] << Table.new(self, i)
|
180
159
|
else
|
181
160
|
text = " [ERROR] Concept #{name} with unkown attribute: #{i.name}"
|
@@ -183,7 +162,6 @@ class Concept
|
|
183
162
|
end
|
184
163
|
end
|
185
164
|
end
|
186
|
-
# rubocop:enable Metrics/MethodLength
|
187
165
|
|
188
166
|
def process_names(value)
|
189
167
|
@names = []
|
@@ -194,7 +172,7 @@ class Concept
|
|
194
172
|
|
195
173
|
def process_tags(value)
|
196
174
|
if value.text.nil? || value.text.size.zero?
|
197
|
-
puts Rainbow("[ERROR] Concept #{name}
|
175
|
+
puts Rainbow("[ERROR] Concept without tags: #{name} ").red.briht
|
198
176
|
exit 1
|
199
177
|
end
|
200
178
|
|
@@ -202,26 +180,24 @@ class Concept
|
|
202
180
|
@data[:tags].collect!(&:strip)
|
203
181
|
end
|
204
182
|
|
205
|
-
# rubocop:disable Metrics/AbcSize
|
206
|
-
# rubocop:disable Metrics/MethodLength
|
207
183
|
def process_def(value)
|
208
|
-
case value.attributes[
|
209
|
-
when
|
184
|
+
case value.attributes["type"]
|
185
|
+
when "image_url"
|
210
186
|
# Link with remote image
|
211
187
|
@data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
|
212
|
-
when
|
188
|
+
when "file"
|
213
189
|
# Load local images and text files
|
214
190
|
@data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
|
215
191
|
when nil
|
216
|
-
|
192
|
+
if value.text.nil?
|
193
|
+
warn Rainbow("[WARN] def: without text!").yellow.bright
|
194
|
+
else
|
195
|
+
@data[:texts] << value.text.strip
|
196
|
+
end
|
217
197
|
else
|
218
198
|
msg = "[ERROR] Unknown type: #{value.attributes['type']}"
|
219
199
|
puts Rainbow(msg).red.bright
|
220
200
|
exit 1
|
221
201
|
end
|
222
202
|
end
|
223
|
-
# rubocop:enable Metrics/AbcSize
|
224
|
-
# rubocop:enable Metrics/MethodLength
|
225
203
|
end
|
226
|
-
# rubocop:enable Metrics/ClassLength
|
227
|
-
# rubocop:enable Style/ClassVars
|
@@ -1,10 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require_relative
|
6
|
-
require_relative 'code_loader'
|
7
|
-
require_relative '../data/project_data'
|
1
|
+
require "rainbow"
|
2
|
+
require "rexml/document"
|
3
|
+
require_relative "code_loader"
|
4
|
+
require_relative "../data/concept"
|
5
|
+
require_relative "../data/project_data"
|
8
6
|
|
9
7
|
# Define methods that load data from XML contents
|
10
8
|
module ContentLoader
|
@@ -25,28 +23,28 @@ module ContentLoader
|
|
25
23
|
|
26
24
|
xmlcontent.root.elements.each do |xmldata|
|
27
25
|
case xmldata.name
|
28
|
-
when
|
26
|
+
when "concept"
|
29
27
|
concepts << read_concept(xmldata, filepath, lang, context)
|
30
|
-
when
|
28
|
+
when "code"
|
31
29
|
codes << read_code(xmldata, filepath)
|
32
30
|
else
|
33
|
-
puts Rainbow("[ERROR] Unkown tag
|
31
|
+
puts Rainbow("[ERROR] Unkown tag: #{xmldata.name}").red
|
32
|
+
puts Rainbow("[INFO ] Only 'concept' and 'code' are available at this level").red
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
36
|
{ concepts: concepts, codes: codes }
|
38
37
|
end
|
39
|
-
# rubocop:enable Metrics/MethodLength
|
40
|
-
# rubocop:enable Metrics/AbcSize
|
41
38
|
|
42
39
|
##
|
43
40
|
# Read lang attr from input XML data
|
44
41
|
# @param xmldata (XML Object)
|
45
42
|
private_class_method def self.read_lang_attribute(xmldata)
|
46
43
|
begin
|
47
|
-
lang = xmldata.root.attributes[
|
44
|
+
lang = xmldata.root.attributes["lang"]
|
48
45
|
rescue StandardError
|
49
46
|
lang = ProjectData.instance.lang
|
47
|
+
puts Rainbow("[WARN ] Default lang: #{lang}").yellow
|
50
48
|
end
|
51
49
|
lang
|
52
50
|
end
|
@@ -56,9 +54,10 @@ module ContentLoader
|
|
56
54
|
# @param xmldata (XML Object)
|
57
55
|
private_class_method def self.read_context_attribute(xmldata)
|
58
56
|
begin
|
59
|
-
context = xmldata.root.attributes[
|
57
|
+
context = xmldata.root.attributes["context"]
|
60
58
|
rescue StandardError
|
61
|
-
context =
|
59
|
+
context = "unknown"
|
60
|
+
puts Rainbow("[WARN ] Default context: #{context}").yellow
|
62
61
|
end
|
63
62
|
context
|
64
63
|
end
|
@@ -27,25 +27,17 @@ module DirectoryLoader
|
|
27
27
|
end
|
28
28
|
|
29
29
|
##
|
30
|
-
# Load
|
30
|
+
# Load files from dirname directory
|
31
31
|
# @param filenames (Array) File name list
|
32
32
|
# @param dirname (String) Base directory
|
33
33
|
def self.load_files(filenames, dirname)
|
34
34
|
output = { concepts: [], codes: [] }
|
35
35
|
filenames.each do |filename|
|
36
36
|
filepath = File.join(dirname, filename)
|
37
|
-
data =
|
37
|
+
data = FileLoader.load(filepath)
|
38
38
|
output[:concepts] += data[:concepts]
|
39
39
|
output[:codes] += data[:codes]
|
40
40
|
end
|
41
41
|
output
|
42
42
|
end
|
43
|
-
|
44
|
-
##
|
45
|
-
# Load one input file
|
46
|
-
# @param filepath (String) Path to input file
|
47
|
-
# @param last (Boolean) True if it is the last filename
|
48
|
-
def self.load_file(filepath, last = false)
|
49
|
-
FileLoader.load(filepath)
|
50
|
-
end
|
51
43
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require 'base64'
|
3
2
|
|
4
3
|
# Methods to load embedded files defined into asker input data file
|
@@ -16,13 +15,13 @@ module EmbeddedFile
|
|
16
15
|
return load_video(value, localdir) if is_video? value
|
17
16
|
|
18
17
|
if is_url? value
|
19
|
-
Logger.verbose Rainbow("[ERROR] Unkown URL
|
18
|
+
Logger.verbose Rainbow("[ERROR] EmbebbedFile. Unkown URL: #{value}").red.bright
|
20
19
|
exit 1
|
21
20
|
end
|
22
21
|
|
23
22
|
filepath = File.join(localdir, value)
|
24
23
|
unless File.exist?(filepath)
|
25
|
-
Logger.verbose Rainbow("[ERROR] File does not exist!: #{filepath}").red.bright
|
24
|
+
Logger.verbose Rainbow("[ERROR] EmbeddedFile. File does not exist!: #{filepath}").red.bright
|
26
25
|
# return { text: "URI error", file: :none, type: :unkown }
|
27
26
|
exit 1
|
28
27
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
require_relative "content_loader"
|
2
|
+
require_relative "haml_loader"
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Methods that load a filename and return list of concepts
|
4
|
+
##
|
5
|
+
# Load a filename and return a Hash with concepts list and code list
|
6
|
+
# return { concepts: [], codes: [] }
|
7
7
|
module FileLoader
|
8
8
|
def self.load(filename)
|
9
9
|
if File.extname(filename).casecmp('.haml').zero?
|
@@ -1,10 +1,7 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require_relative 'directory_loader'
|
4
2
|
require_relative '../ai/concept_ai'
|
5
3
|
require_relative '../data/world'
|
6
4
|
|
7
|
-
# Load DATA defined into our Project
|
8
5
|
module InputLoader
|
9
6
|
##
|
10
7
|
# Load input data from every input directory
|
@@ -12,7 +9,6 @@ module InputLoader
|
|
12
9
|
def self.load(inputdirs, internet = true)
|
13
10
|
data = { concepts: [], codes: [], world: nil,
|
14
11
|
concepts_ai: [], codes_ai: [] }
|
15
|
-
#Logger.verboseln "\n[INFO] Loading input data"
|
16
12
|
inputdirs.each do |dirname|
|
17
13
|
temp = DirectoryLoader.load(dirname)
|
18
14
|
data[:concepts] += temp[:concepts]
|
data/lib/asker/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asker-tool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Vargas Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: haml
|