asker-tool 2.1.2
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/LICENSE +674 -0
- data/README.md +53 -0
- data/bin/asker +4 -0
- data/docs/changelog/v2.1.md +99 -0
- data/docs/commands.md +15 -0
- data/docs/contributions.md +18 -0
- data/docs/history.md +40 -0
- data/docs/idea.md +44 -0
- data/docs/inputs/README.md +39 -0
- data/docs/inputs/code.md +69 -0
- data/docs/inputs/concepts.md +142 -0
- data/docs/inputs/jedi.md +68 -0
- data/docs/inputs/tables.md +112 -0
- data/docs/inputs/templates.md +87 -0
- data/docs/install/README.md +38 -0
- data/docs/install/manual.md +26 -0
- data/docs/install/scripts.md +26 -0
- data/docs/revise/asker-file.md +41 -0
- data/docs/revise/buenas-practicas/01-convocatoria.md +30 -0
- data/docs/revise/buenas-practicas/02-formulario.md +35 -0
- data/docs/revise/buenas-practicas/03-descripcion.md +63 -0
- data/docs/revise/buenas-practicas/04-resultados.md +17 -0
- data/docs/revise/buenas-practicas/05-reproducir.md +10 -0
- data/docs/revise/ejemplos/01/README.md +27 -0
- data/docs/revise/ejemplos/02/README.md +31 -0
- data/docs/revise/ejemplos/03/README.md +31 -0
- data/docs/revise/ejemplos/04/README.md +37 -0
- data/docs/revise/ejemplos/05/README.md +25 -0
- data/docs/revise/ejemplos/06/README.md +43 -0
- data/docs/revise/ejemplos/README.md +11 -0
- data/docs/revise/projects.md +74 -0
- data/lib/asker.rb +103 -0
- data/lib/asker/ai/ai.rb +70 -0
- data/lib/asker/ai/ai_calculate.rb +55 -0
- data/lib/asker/ai/concept_ai.rb +49 -0
- data/lib/asker/ai/question.rb +58 -0
- data/lib/asker/ai/stages/base_stage.rb +16 -0
- data/lib/asker/ai/stages/main.rb +8 -0
- data/lib/asker/ai/stages/stage_b.rb +87 -0
- data/lib/asker/ai/stages/stage_d.rb +160 -0
- data/lib/asker/ai/stages/stage_f.rb +156 -0
- data/lib/asker/ai/stages/stage_i.rb +140 -0
- data/lib/asker/ai/stages/stage_s.rb +52 -0
- data/lib/asker/ai/stages/stage_t.rb +170 -0
- data/lib/asker/application.rb +30 -0
- data/lib/asker/checker.rb +356 -0
- data/lib/asker/cli.rb +85 -0
- data/lib/asker/code/ai/base_code_ai.rb +48 -0
- data/lib/asker/code/ai/code_ai_factory.rb +26 -0
- data/lib/asker/code/ai/javascript_code_ai.rb +167 -0
- data/lib/asker/code/ai/python_code_ai.rb +167 -0
- data/lib/asker/code/ai/ruby_code_ai.rb +169 -0
- data/lib/asker/code/ai/sql_code_ai.rb +69 -0
- data/lib/asker/code/code.rb +53 -0
- data/lib/asker/data/column.rb +62 -0
- data/lib/asker/data/concept.rb +183 -0
- data/lib/asker/data/data_field.rb +87 -0
- data/lib/asker/data/row.rb +93 -0
- data/lib/asker/data/table.rb +96 -0
- data/lib/asker/data/template.rb +65 -0
- data/lib/asker/data/world.rb +53 -0
- data/lib/asker/exporter/code_gift_exporter.rb +35 -0
- data/lib/asker/exporter/code_screen_exporter.rb +45 -0
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +33 -0
- data/lib/asker/exporter/concept_ai_screen_exporter.rb +115 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +33 -0
- data/lib/asker/exporter/concept_doc_exporter.rb +21 -0
- data/lib/asker/exporter/concept_screen_exporter.rb +25 -0
- data/lib/asker/exporter/main.rb +9 -0
- data/lib/asker/files/config.ini +40 -0
- data/lib/asker/formatter/code_string_formatter.rb +16 -0
- data/lib/asker/formatter/concept_doc_formatter.rb +37 -0
- data/lib/asker/formatter/concept_string_formatter.rb +66 -0
- data/lib/asker/formatter/question_gift_formatter.rb +65 -0
- data/lib/asker/formatter/question_hash_formatter.rb +40 -0
- data/lib/asker/formatter/question_moodlexml_formatter.rb +71 -0
- data/lib/asker/formatter/rb2haml_formatter.rb +26 -0
- data/lib/asker/lang/lang.rb +42 -0
- data/lib/asker/lang/lang_factory.rb +19 -0
- data/lib/asker/lang/text_actions.rb +150 -0
- data/lib/asker/loader/code_loader.rb +53 -0
- data/lib/asker/loader/content_loader.rb +101 -0
- data/lib/asker/loader/directory_loader.rb +58 -0
- data/lib/asker/loader/file_loader.rb +33 -0
- data/lib/asker/loader/image_url_loader.rb +61 -0
- data/lib/asker/loader/input_loader.rb +24 -0
- data/lib/asker/loader/project_loader.rb +71 -0
- data/lib/asker/logger.rb +21 -0
- data/lib/asker/project.rb +170 -0
- metadata +261 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require_relative '../project'
|
5
|
+
require_relative '../formatter/question_hash_formatter'
|
6
|
+
|
7
|
+
# Use to export data from ConceptIA to YAML format
|
8
|
+
module ConceptAIYAMLExporter
|
9
|
+
def self.export_all(concepts_ai)
|
10
|
+
questions = []
|
11
|
+
concepts_ai.each do |concept_ai|
|
12
|
+
questions += get_questions_from concept_ai
|
13
|
+
end
|
14
|
+
project = Project.instance
|
15
|
+
params = { lang: project.get(:lang) ,
|
16
|
+
projectname: project.get(:projectname) }
|
17
|
+
output = { params: params, questions: questions }
|
18
|
+
project.yamlfile.write(output.to_yaml)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.get_questions_from(concept_ai)
|
22
|
+
data = []
|
23
|
+
return data unless concept_ai.process?
|
24
|
+
stages = Project.instance.stages
|
25
|
+
stages.each_key do |stage|
|
26
|
+
concept_ai.questions[stage].each do |question|
|
27
|
+
question.lang = concept_ai.lang
|
28
|
+
data << QuestionHashFormatter.to_hash(question)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
data
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative '../project'
|
4
|
+
require_relative '../formatter/concept_doc_formatter'
|
5
|
+
|
6
|
+
class ConceptDocExporter
|
7
|
+
|
8
|
+
def initialize(concepts)
|
9
|
+
@concepts = concepts
|
10
|
+
end
|
11
|
+
|
12
|
+
def export
|
13
|
+
file = Project.instance.lessonfile
|
14
|
+
@concepts.each do |concept|
|
15
|
+
if concept.process
|
16
|
+
file.write(ConceptDocFormatter.to_s(concept))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
require_relative '../formatter/concept_string_formatter'
|
3
|
+
|
4
|
+
# Show Concept Data on screen
|
5
|
+
module ConceptScreenExporter
|
6
|
+
def self.export_all(concepts)
|
7
|
+
project = Project.instance
|
8
|
+
return if project.show_mode == :none
|
9
|
+
msg = "\n[INFO] Showing concept data <"
|
10
|
+
msg += Rainbow(project.show_mode.to_s).bright + '>'
|
11
|
+
project.verbose msg
|
12
|
+
|
13
|
+
case project.show_mode
|
14
|
+
when :resume
|
15
|
+
s = "* Concepts (#{concepts.count}): "
|
16
|
+
concepts.each { |c| s += c.name + ', ' }
|
17
|
+
project.verbose s
|
18
|
+
when :default
|
19
|
+
# Only show Concepts with process attr true
|
20
|
+
concepts.each do |c|
|
21
|
+
project.verbose ConceptStringFormatter.to_s(c) if c.process?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
require_relative 'code_gift_exporter'
|
3
|
+
require_relative 'code_screen_exporter'
|
4
|
+
|
5
|
+
require_relative 'concept_ai_gift_exporter'
|
6
|
+
require_relative 'concept_ai_screen_exporter'
|
7
|
+
require_relative 'concept_ai_yaml_exporter'
|
8
|
+
require_relative 'concept_doc_exporter'
|
9
|
+
require_relative 'concept_screen_exporter'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
[global]
|
2
|
+
; Connect Google and download find images URLs
|
3
|
+
; Accept yes|no
|
4
|
+
internet = no
|
5
|
+
|
6
|
+
[questions]
|
7
|
+
; Exclude questions with this texts into their names.
|
8
|
+
; Accept Comma separated strings.
|
9
|
+
exclude =
|
10
|
+
|
11
|
+
; ### stage_b ###
|
12
|
+
; b1: b1match4x4, b1match3x1misspelled, b1match3x1
|
13
|
+
; ### stage_d ###
|
14
|
+
; d1: d1choose, d1none, d1none-misspelled
|
15
|
+
; d2: d2def-mispelled, d2name-mispelled, d2true, d2false-misspelled
|
16
|
+
; d3: d3hidden
|
17
|
+
; d4: d4filtered
|
18
|
+
; ### stage_f
|
19
|
+
; f1: f1true, f1short, f1name-misspelled, f1true-misspelled, f1false
|
20
|
+
; f2: f2outsider
|
21
|
+
; f3: f3filtered
|
22
|
+
; ### stage_i
|
23
|
+
; i1
|
24
|
+
; i2
|
25
|
+
; i3
|
26
|
+
; i4
|
27
|
+
; ### stage_s
|
28
|
+
; s1
|
29
|
+
; ### stage_t
|
30
|
+
; t1table
|
31
|
+
; t2table
|
32
|
+
; t3table
|
33
|
+
; t4table
|
34
|
+
; t5table
|
35
|
+
; t6table
|
36
|
+
; t7table
|
37
|
+
; t8table
|
38
|
+
; t9table
|
39
|
+
; ### code
|
40
|
+
; code1
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rainbow'
|
4
|
+
require 'terminal-table'
|
5
|
+
|
6
|
+
# Define methods to trasnforme Code object into String
|
7
|
+
module CodeStringFormatter
|
8
|
+
def self.to_s(code)
|
9
|
+
t = Terminal::Table.new
|
10
|
+
msg = Rainbow(code.filename).white.bg(:blue).bright
|
11
|
+
t.add_row [Rainbow('Code').bright, msg]
|
12
|
+
t.add_row [Rainbow('Type').blue, code.type.to_s]
|
13
|
+
t.add_row [Rainbow('Lines').blue, code.lines_to_s(code.lines)]
|
14
|
+
"#{t}\n"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'rainbow'
|
4
|
+
require 'terminal-table'
|
5
|
+
|
6
|
+
require_relative '../project'
|
7
|
+
|
8
|
+
##
|
9
|
+
# Formatter Concept to Doc
|
10
|
+
module ConceptDocFormatter
|
11
|
+
##
|
12
|
+
# Formatter Concept into Doc
|
13
|
+
# @param concept (Concept)
|
14
|
+
def self.to_s(concept)
|
15
|
+
out = ''
|
16
|
+
out << "\n#{Rainbow(concept.name).bg(:blue).bright}\n\n"
|
17
|
+
concept.texts.each { |i| out << "* #{i}\n" }
|
18
|
+
out << "\n"
|
19
|
+
concept.tables.each do |table|
|
20
|
+
out << table_to_s(table)
|
21
|
+
end
|
22
|
+
out
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Formatter Table to Doc
|
27
|
+
# @param table (Table)
|
28
|
+
# @return String
|
29
|
+
def self.table_to_s(table)
|
30
|
+
my_screen_table = Terminal::Table.new do |st|
|
31
|
+
st << table.fields
|
32
|
+
st << :separator
|
33
|
+
table.rows.each { |r| st.add_row r }
|
34
|
+
end
|
35
|
+
"#{my_screen_table}\n"
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rainbow'
|
4
|
+
require 'terminal-table'
|
5
|
+
|
6
|
+
# Define methods to transform Concept into String
|
7
|
+
module ConceptStringFormatter
|
8
|
+
##
|
9
|
+
# Formatter Concept to String
|
10
|
+
# @param concept (Concept)
|
11
|
+
# @return String
|
12
|
+
def self.to_s(concept)
|
13
|
+
tt = Terminal::Table.new
|
14
|
+
rows = get_tt_rows(concept)
|
15
|
+
rows.each { |row| tt.add_row row }
|
16
|
+
"#{tt}\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
# rubocop:disable Metrics/AbcSize
|
20
|
+
# rubocop:disable Metrics/MethodLength
|
21
|
+
def self.get_tt_rows(concept)
|
22
|
+
rows = []
|
23
|
+
rows << [Rainbow(concept.id.to_s).bright,
|
24
|
+
Rainbow(concept.name(:screen)).white.bg(:blue).bright +
|
25
|
+
" (lang=#{concept.lang.lang}) "]
|
26
|
+
rows << [Rainbow('Filename').blue, concept.filename]
|
27
|
+
rows << [Rainbow('Context').blue, concept.context.join(', ').to_s]
|
28
|
+
rows << [Rainbow('Tags').blue, concept.tags.join(', ').to_s]
|
29
|
+
rows << [Rainbow('Reference to').blue,
|
30
|
+
concept.reference_to.join(', ')[0...70].to_s]
|
31
|
+
rows << [Rainbow('Referenced by').blue,
|
32
|
+
concept.referenced_by.join(', ')[0...70].to_s]
|
33
|
+
rows << format_texts(concept)
|
34
|
+
rows << [Rainbow('.def(images)').blue, concept.images.size.to_s]
|
35
|
+
rows << format_tables(concept)
|
36
|
+
rows << format_neighbors(concept)
|
37
|
+
end
|
38
|
+
# rubocop:enable Metrics/AbcSize
|
39
|
+
# rubocop:enable Metrics/MethodLength
|
40
|
+
|
41
|
+
def self.format_texts(concept)
|
42
|
+
list = []
|
43
|
+
concept.texts.each do |i|
|
44
|
+
if i.size < 60
|
45
|
+
list << i.to_s
|
46
|
+
next
|
47
|
+
end
|
48
|
+
list << i[0...70].to_s + '...'
|
49
|
+
end
|
50
|
+
[Rainbow('.def(text)').blue, list.join("\n")]
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.format_tables(concept)
|
54
|
+
return [] if concept.tables.count.zero?
|
55
|
+
|
56
|
+
list = concept.tables.map(&:to_s)
|
57
|
+
[Rainbow('.tables').color(:blue), list.join("\n")]
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.format_neighbors(concept)
|
61
|
+
list = concept.neighbors[0..4].map do |i|
|
62
|
+
i[:concept].name(:screen) + '(' + i[:value].to_s[0..4] + ')'
|
63
|
+
end
|
64
|
+
[Rainbow('.neighbors').blue, list.join("\n")]
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Transform Questions into Gift format
|
4
|
+
module QuestionGiftFormatter
|
5
|
+
def self.to_s(question)
|
6
|
+
@question = question
|
7
|
+
# Return question using gift format
|
8
|
+
cond = @question.comment.nil? && @question.comment.empty?
|
9
|
+
s = "// #{@question.comment}\n" unless cond
|
10
|
+
s << "::#{@question.name}::[html]#{sanitize(@question.text)}\n"
|
11
|
+
|
12
|
+
case @question.type
|
13
|
+
when :choice
|
14
|
+
s += "{\n"
|
15
|
+
a = [" =#{sanitize(@question.good)}\n"]
|
16
|
+
penalties = ['', '%-50%', '%-33.33333%', '%-25%', '%-20%']
|
17
|
+
penalty = penalties[@question.bads.size]
|
18
|
+
|
19
|
+
@question.bads.each { |i| a << (" ~#{penalty}" + sanitize(i) + "\n") }
|
20
|
+
a.shuffle! if @question.shuffle?
|
21
|
+
a.each do |i|
|
22
|
+
text = i
|
23
|
+
text = i[0, 220] + '...(ERROR: text too long)' if text.size > 255
|
24
|
+
s << text
|
25
|
+
end
|
26
|
+
s += " #####{sanitize(@question.feedback.to_s)}\n" if @question.feedback
|
27
|
+
s += "}\n\n"
|
28
|
+
when :boolean
|
29
|
+
s << "{#{@question.good}#####{sanitize(@question.feedback.to_s)}}\n\n"
|
30
|
+
when :match
|
31
|
+
s << "{\n"
|
32
|
+
a = []
|
33
|
+
@question.matching.each do |i, j|
|
34
|
+
i = i[0, 220] + '...(ERROR: text too long)' if i.size > 255
|
35
|
+
j = j[0, 220] + '...(ERROR: text too long)' if j.size > 255
|
36
|
+
a << " =#{sanitize(i)} -> #{sanitize(j)}\n"
|
37
|
+
end
|
38
|
+
a.shuffle! if @question.shuffle?
|
39
|
+
a.each { |i| s << i }
|
40
|
+
s << "}\n\n"
|
41
|
+
when :short
|
42
|
+
s << "{\n"
|
43
|
+
@question.shorts.uniq!
|
44
|
+
@question.shorts.each do |i|
|
45
|
+
text = i
|
46
|
+
text = i[0, 220] + '...(ERROR: too long)' if text.size > 255
|
47
|
+
s << " =%100%#{text}#\n"
|
48
|
+
end
|
49
|
+
s << " #####{sanitize(@question.feedback.to_s)}\n" if @question.feedback
|
50
|
+
s << "}\n\n"
|
51
|
+
end
|
52
|
+
s
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.sanitize(input = '')
|
56
|
+
output = input.dup
|
57
|
+
output.gsub!("#", "\\#")
|
58
|
+
output.gsub!("\n", " ")
|
59
|
+
#output.gsub!(":", "\\:")
|
60
|
+
output.gsub!("=", "\\=")
|
61
|
+
output.gsub!("\{", "\\{")
|
62
|
+
output.gsub!("\}", "\\}")
|
63
|
+
output
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
# Transform Questions into YAML format
|
3
|
+
module QuestionHashFormatter
|
4
|
+
def self.to_hash(question)
|
5
|
+
@question = question
|
6
|
+
# Return question using YAML format
|
7
|
+
s = {}
|
8
|
+
s[:comment] = @question.comment
|
9
|
+
s[:name] = @question.name
|
10
|
+
s[:text] = sanitize(@question.text)
|
11
|
+
s[:type] = @question.type
|
12
|
+
s[:feedback] = sanitize(@question.feedback.to_s)
|
13
|
+
s[:lang] = @question.lang.code.to_sym
|
14
|
+
case @question.type
|
15
|
+
when :choice
|
16
|
+
s[:answer] = sanitize(@question.good)
|
17
|
+
s[:options] = (@question.bads + [@question.good]).shuffle
|
18
|
+
when :boolean
|
19
|
+
s[:answer] = @question.good
|
20
|
+
when :match
|
21
|
+
s[:answer] = @question.matching
|
22
|
+
s[:matching] = @question.matching
|
23
|
+
when :short
|
24
|
+
@question.shorts.uniq!
|
25
|
+
s[:answer] = @question.shorts
|
26
|
+
end
|
27
|
+
s
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.sanitize(input = '')
|
31
|
+
output = input.dup
|
32
|
+
output.gsub!("#", "\\#")
|
33
|
+
output.gsub!("\n", " ")
|
34
|
+
#output.gsub!(":", "\\:")
|
35
|
+
output.gsub!("=", "\\=")
|
36
|
+
output.gsub!("\{", "\\{")
|
37
|
+
output.gsub!("\}", "\\}")
|
38
|
+
output
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Transform Questions into Gift format
|
4
|
+
module QuestionMoodleXMLFormatter
|
5
|
+
def self.to_s(question)
|
6
|
+
@question = question
|
7
|
+
|
8
|
+
case @question.type
|
9
|
+
when :choice
|
10
|
+
s += choice_to_s(question)
|
11
|
+
when :boolean
|
12
|
+
when :match
|
13
|
+
when :short
|
14
|
+
end
|
15
|
+
s.flaten!
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.choice_to_s(question)
|
19
|
+
s = []
|
20
|
+
|
21
|
+
penalties = ['', '%-50%', '%-33.33333%', '%-25%', '%-20%']
|
22
|
+
penalty = penalties[question.bads.size]
|
23
|
+
|
24
|
+
s << "<!-- question: #{question.name} -->"
|
25
|
+
s << '<question type="multichoice">'
|
26
|
+
s << ' <name>'
|
27
|
+
s << " <text>#{question.name}</text>"
|
28
|
+
s << ' </name>'
|
29
|
+
s << ' <questiontext format="html">'
|
30
|
+
s << " <text><![CDATA[#{question.text}]]></text>"
|
31
|
+
s << ' </questiontext>'
|
32
|
+
s << ' <generalfeedback format="html">'
|
33
|
+
s << " <text>#{question.feedback}</text>"
|
34
|
+
s << ' </generalfeedback>'
|
35
|
+
s << ' <defaultgrade>1.0000000</defaultgrade>'
|
36
|
+
s << " <penalty>#{penalty}</penalty>"
|
37
|
+
s << ' <hidden>0</hidden>'
|
38
|
+
s << ' <single>true</single>'
|
39
|
+
s << " <shuffleanswers>#{question.shuffle?}</shuffleanswers>"
|
40
|
+
s << ' <answernumbering>abc</answernumbering>'
|
41
|
+
s << ' <incorrectfeedback format="html">'
|
42
|
+
s << " <text>#{question.feedback}</text>"
|
43
|
+
s << ' </incorrectfeedback>'
|
44
|
+
s << ' <answer fraction="100" format="html">'
|
45
|
+
s << " <text>#{question.good}</text>"
|
46
|
+
s << ' </answer>'
|
47
|
+
s << ' <answer fraction="-25" format="html">'
|
48
|
+
s << " <text>#{question.bad[0]}</text>"
|
49
|
+
s << ' </answer>'
|
50
|
+
s << ' </question>'
|
51
|
+
s << ' <answer fraction="-25" format="html">'
|
52
|
+
s << " <text>#{question.bad[1]}</text>"
|
53
|
+
s << ' </answer>'
|
54
|
+
s << ' </question>'
|
55
|
+
s << ' <answer fraction="-25" format="html">'
|
56
|
+
s << " <text>#{question.bad[2]}</text>"
|
57
|
+
s << ' </answer>'
|
58
|
+
s << ' </question>'
|
59
|
+
s
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.sanitize(input = '')
|
63
|
+
output = input.dup
|
64
|
+
output.tr!("\n", " ")
|
65
|
+
output.tr!(":", "\:")
|
66
|
+
output.tr!("=", "\\=")
|
67
|
+
# output.gsub!('{', "\\{")
|
68
|
+
# output.gsub!('}', "\\}")
|
69
|
+
output
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# UNDER DEVELOPMENT!!
|
2
|
+
|
3
|
+
module Rb2HamlExporter
|
4
|
+
def self.export(filename)
|
5
|
+
check_file filename
|
6
|
+
rbcontent = File.read(filename)
|
7
|
+
puts rbcontent
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.check_file(filename)
|
11
|
+
unless File.extname(filename).casecmp('.rb').zero?
|
12
|
+
msg = "[ERROR] Rb2HamlExporter: File name error #{filename}"
|
13
|
+
raise msg
|
14
|
+
end
|
15
|
+
unless File.exist? filename
|
16
|
+
msg = "[ERROR] Rb2HamlExporter: File #{filename} not found!"
|
17
|
+
raise msg
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Map
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
Rb2HamlExporter.export('docs/examples/home/rb/furniture.rb')
|