asker-tool 2.1.2 → 2.1.7

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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +0 -0
  3. data/README.md +17 -18
  4. data/bin/asker +1 -0
  5. data/lib/asker.rb +43 -74
  6. data/lib/asker/ai/ai.rb +4 -0
  7. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  8. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  9. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  10. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  11. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  12. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  13. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  14. data/lib/asker/ai/concept_ai.rb +1 -0
  15. data/lib/asker/ai/stages/stage_t.rb +76 -76
  16. data/lib/asker/application.rb +19 -3
  17. data/lib/asker/checker.rb +152 -53
  18. data/lib/asker/cli.rb +19 -22
  19. data/lib/asker/data/code.rb +73 -0
  20. data/lib/asker/data/column.rb +31 -21
  21. data/lib/asker/data/concept.rb +42 -45
  22. data/lib/asker/data/data_field.rb +14 -0
  23. data/lib/asker/data/row.rb +75 -52
  24. data/lib/asker/data/table.rb +89 -42
  25. data/lib/asker/data/world.rb +58 -32
  26. data/lib/asker/{exporter/code_screen_exporter.rb → displayer/code_displayer.rb} +6 -6
  27. data/lib/asker/displayer/concept_ai_displayer.rb +132 -0
  28. data/lib/asker/displayer/concept_displayer.rb +29 -0
  29. data/lib/asker/displayer/stats_displayer.rb +14 -0
  30. data/lib/asker/exporter/code_gift_exporter.rb +10 -11
  31. data/lib/asker/exporter/concept_ai_gift_exporter.rb +23 -11
  32. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +9 -7
  33. data/lib/asker/exporter/concept_doc_exporter.rb +9 -15
  34. data/lib/asker/exporter/output_file_exporter.rb +18 -0
  35. data/lib/asker/files/config.ini +37 -0
  36. data/lib/asker/files/example-code.haml +0 -0
  37. data/lib/asker/files/example-concept.haml +29 -0
  38. data/lib/asker/files/language/du/templates.yaml +50 -0
  39. data/lib/asker/files/language/en/connectors.yaml +44 -0
  40. data/lib/asker/files/language/en/mistakes.yaml +37 -0
  41. data/lib/asker/files/language/en/templates.yaml +29 -0
  42. data/lib/asker/files/language/es/connectors.yaml +92 -0
  43. data/lib/asker/files/language/es/mistakes.yaml +82 -0
  44. data/lib/asker/files/language/es/templates.yaml +29 -0
  45. data/lib/asker/files/language/fr/connectors.yaml +92 -0
  46. data/lib/asker/files/language/fr/mistakes.yaml +82 -0
  47. data/lib/asker/files/language/fr/templates.yaml +29 -0
  48. data/lib/asker/files/language/javascript/connectors.yaml +11 -0
  49. data/lib/asker/files/language/javascript/mistakes.yaml +30 -0
  50. data/lib/asker/files/language/javascript/templates.yaml +3 -0
  51. data/lib/asker/files/language/math/connectors.yaml +2 -0
  52. data/lib/asker/files/language/math/mistakes.yaml +2 -0
  53. data/lib/asker/files/language/math/templates.yaml +1 -0
  54. data/lib/asker/files/language/python/connectors.yaml +11 -0
  55. data/lib/asker/files/language/python/mistakes.yaml +26 -0
  56. data/lib/asker/files/language/python/templates.yaml +3 -0
  57. data/lib/asker/files/language/ruby/connectors.yaml +11 -0
  58. data/lib/asker/files/language/ruby/mistakes.yaml +33 -0
  59. data/lib/asker/files/language/ruby/templates.yaml +3 -0
  60. data/lib/asker/files/language/sql/connectors.yaml +6 -0
  61. data/lib/asker/files/language/sql/mistakes.yaml +11 -0
  62. data/lib/asker/files/language/sql/templates.yaml +2 -0
  63. data/lib/asker/formatter/concept_string_formatter.rb +9 -8
  64. data/lib/asker/formatter/question_gift_formatter.rb +9 -1
  65. data/lib/asker/lang/lang.rb +18 -12
  66. data/lib/asker/lang/lang_factory.rb +26 -5
  67. data/lib/asker/lang/text_actions.rb +87 -69
  68. data/lib/asker/loader/code_loader.rb +3 -3
  69. data/lib/asker/loader/content_loader.rb +9 -5
  70. data/lib/asker/loader/file_loader.rb +2 -11
  71. data/lib/asker/loader/haml_loader.rb +15 -0
  72. data/lib/asker/loader/image_url_loader.rb +5 -8
  73. data/lib/asker/loader/input_loader.rb +23 -7
  74. data/lib/asker/loader/project_loader.rb +32 -29
  75. data/lib/asker/logger.rb +3 -4
  76. data/lib/asker/project.rb +28 -52
  77. data/lib/asker/skeleton.rb +73 -0
  78. metadata +62 -73
  79. data/docs/changelog/v2.1.md +0 -99
  80. data/docs/commands.md +0 -15
  81. data/docs/contributions.md +0 -18
  82. data/docs/history.md +0 -40
  83. data/docs/idea.md +0 -44
  84. data/docs/inputs/README.md +0 -39
  85. data/docs/inputs/code.md +0 -69
  86. data/docs/inputs/concepts.md +0 -142
  87. data/docs/inputs/jedi.md +0 -68
  88. data/docs/inputs/tables.md +0 -112
  89. data/docs/inputs/templates.md +0 -87
  90. data/docs/install/README.md +0 -38
  91. data/docs/install/manual.md +0 -26
  92. data/docs/install/scripts.md +0 -26
  93. data/docs/revise/asker-file.md +0 -41
  94. data/docs/revise/buenas-practicas/01-convocatoria.md +0 -30
  95. data/docs/revise/buenas-practicas/02-formulario.md +0 -35
  96. data/docs/revise/buenas-practicas/03-descripcion.md +0 -63
  97. data/docs/revise/buenas-practicas/04-resultados.md +0 -17
  98. data/docs/revise/buenas-practicas/05-reproducir.md +0 -10
  99. data/docs/revise/ejemplos/01/README.md +0 -27
  100. data/docs/revise/ejemplos/02/README.md +0 -31
  101. data/docs/revise/ejemplos/03/README.md +0 -31
  102. data/docs/revise/ejemplos/04/README.md +0 -37
  103. data/docs/revise/ejemplos/05/README.md +0 -25
  104. data/docs/revise/ejemplos/06/README.md +0 -43
  105. data/docs/revise/ejemplos/README.md +0 -11
  106. data/docs/revise/projects.md +0 -74
  107. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  108. data/lib/asker/code/code.rb +0 -53
  109. data/lib/asker/exporter/concept_ai_screen_exporter.rb +0 -115
  110. data/lib/asker/exporter/concept_screen_exporter.rb +0 -25
  111. data/lib/asker/exporter/main.rb +0 -9
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'terminal-table'
4
+ require_relative '../logger'
4
5
 
5
6
  # Export Code into Screen
6
- module CodeScreenExporter
7
- def self.export_all(codes)
8
- project = Project.instance
9
- return if project.show_mode == :none || codes.nil? || codes.size.zero?
7
+ module CodeDisplayer
8
+ def self.show(codes)
9
+ return if codes.nil? || codes.size.zero?
10
10
 
11
11
  total_c = total_q = total_e = 0
12
12
  my_screen_table = Terminal::Table.new do |st|
@@ -39,7 +39,7 @@ module CodeScreenExporter
39
39
  Rainbow((total_q / total_e.to_f).round(2)).bright]
40
40
  return unless total_c.positive?
41
41
 
42
- project.verboseln "\n[INFO] Showing CODE statistics"
43
- project.verboseln my_screen_table.to_s
42
+ Logger.verboseln "\n[INFO] Showing CODE statistics"
43
+ Logger.verboseln my_screen_table.to_s
44
44
  end
45
45
  end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'terminal-table'
4
+ require_relative '../application'
5
+ require_relative '../logger'
6
+
7
+ # Display ConceptAI stat on screen
8
+ class ConceptAIDisplayer
9
+ ##
10
+ # Display ConceptAI stat on screen
11
+ # @param concepts_ai (Array)
12
+ def self.show(concepts_ai)
13
+ stages = Application.instance.config['questions']['stages']
14
+ # Create table HEAD
15
+ screen_table = Terminal::Table.new do |st|
16
+ title = ['Concept', 'Questions', 'Entries', 'xFactor']
17
+ %w[d b f i s t].each do |i|
18
+ if stages.include? i.to_sym
19
+ title << i
20
+ next
21
+ end
22
+ title << Rainbow(i).yellow.bright
23
+ end
24
+ st << title
25
+ st << :separator
26
+ end
27
+ # Create table BODY
28
+ total = {}
29
+ total[:q] = total[:e] = total[:c] = 0
30
+ total[:sd] = total[:sb] = total[:sf] = 0
31
+ total[:si] = total[:ss] = total[:st] = 0
32
+
33
+ concepts_ai.each do |concept_ai|
34
+ next unless concept_ai.process?
35
+
36
+ e = concept_ai.texts.size
37
+ concept_ai.tables.each { |t| e += t.fields.size * t.rows.size }
38
+
39
+ sd = sb = sf = 0
40
+ si = ss = st = 0
41
+ sd = concept_ai.questions[:d].size if stages.include? :d
42
+ sb = concept_ai.questions[:b].size if stages.include? :b
43
+ sf = concept_ai.questions[:f].size if stages.include? :f
44
+ si = concept_ai.questions[:i].size if stages.include? :i
45
+ ss = concept_ai.questions[:s].size if stages.include? :s
46
+ st = concept_ai.questions[:t].size if stages.include? :t
47
+ t = sd + sb + sf + si + ss + st
48
+
49
+ factor = 'Unkown'
50
+ factor = (t.to_f / e).round(2).to_s unless e.zero?
51
+ screen_table.add_row [Rainbow(concept_ai.name(:screen)).green.bright,
52
+ t, e, factor, sd, sb, sf, si, ss, st]
53
+
54
+ total[:q] += t
55
+ total[:e] += e
56
+ total[:c] += 1
57
+ total[:sd] += sd
58
+ total[:sb] += sb
59
+ total[:sf] += sf
60
+ total[:si] += si
61
+ total[:ss] += ss
62
+ total[:st] += st
63
+ end
64
+ return if total[:c].zero? # No concepts to be process?
65
+
66
+ # Add row with excluded questions
67
+ export_excluded_questions(screen_table, concepts_ai)
68
+
69
+ # Create table TAIL
70
+ screen_table.add_separator
71
+ screen_table.add_row [Rainbow("TOTAL = #{total[:c]}").bright,
72
+ Rainbow(total[:q].to_s).bright,
73
+ Rainbow(total[:e].to_s).bright,
74
+ Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
75
+ total[:sd], total[:sb], total[:sf],
76
+ total[:si], total[:ss], total[:st]]
77
+ export_notes
78
+ Logger.verbose "#{screen_table}\n"
79
+ end
80
+
81
+ private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
82
+ # Create table BODY
83
+ total = {}
84
+ total[:q] = total[:c] = 0
85
+ total[:sd] = total[:sb] = total[:sf] = 0
86
+ total[:si] = total[:ss] = total[:st] = 0
87
+
88
+ concepts_ai.each do |concept_ai|
89
+ next unless concept_ai.process?
90
+
91
+ sd = concept_ai.excluded_questions[:d].size
92
+ sb = concept_ai.excluded_questions[:b].size
93
+ sf = concept_ai.excluded_questions[:f].size
94
+ si = concept_ai.excluded_questions[:i].size
95
+ ss = concept_ai.excluded_questions[:s].size
96
+ st = concept_ai.excluded_questions[:t].size
97
+ t = sd + sb + sf + si + ss + st
98
+
99
+ total[:q] += t
100
+ total[:c] += 1
101
+ total[:sd] += sd
102
+ total[:sb] += sb
103
+ total[:sf] += sf
104
+ total[:si] += si
105
+ total[:ss] += ss
106
+ total[:st] += st
107
+ end
108
+ screen_table.add_row [Rainbow('Excluded questions').yellow.bright,
109
+ total[:q], '-', '-',
110
+ total[:sd], total[:sb],
111
+ total[:sf], total[:si],
112
+ total[:ss], total[:st]]
113
+ end
114
+
115
+ private_class_method def self.export_notes
116
+ Logger.verbose "\n[INFO] Showing CONCEPT statistics\n"
117
+ Logger.verbose ' * Exclude questions: ' +
118
+ Application.instance.config['questions']['exclude'].to_s
119
+ Logger.verbose ' * Annotations:'
120
+ Logger.verbose ' ├── (d) Definitions <= Concept.def'
121
+ Logger.verbose ' ├── (b) Table Matching <= ' \
122
+ 'Concept.table.rows.columns'
123
+ Logger.verbose ' ├── (f) Tables 1 Field <= Concept.table.fields.size==1'
124
+ Logger.verbose ' ├── (i) Images URL <= ' \
125
+ "Concept.def{:type => 'image_url'}"
126
+ Logger.verbose ' ├── (s) Sequences <= ' \
127
+ "Concept.table{:sequence => '...'}"
128
+ Logger.verbose ' └── (t) Table Rows&Cols <= ' \
129
+ 'Concept.table.rows.columns'
130
+ Logger.verbose "\n"
131
+ end
132
+ end
@@ -0,0 +1,29 @@
1
+
2
+ require_relative '../application'
3
+ require_relative '../formatter/concept_string_formatter'
4
+ require_relative '../logger'
5
+
6
+ # Show Concept Data on screen
7
+ module ConceptDisplayer
8
+ ##
9
+ # Show concepts on screen
10
+ # @param concepts (Array)
11
+ def self.show(concepts)
12
+ show_mode = Application.instance.config['global']['show_mode']
13
+ return unless show_mode
14
+
15
+ msg = "\n[INFO] Showing concept data (#{Rainbow(show_mode).bright})"
16
+ Logger.verbose msg
17
+ case show_mode
18
+ when 'resume'
19
+ s = "* Concepts (#{concepts.count}): "
20
+ concepts.each { |c| s += c.name + ', ' }
21
+ Logger.verbose s
22
+ when 'default'
23
+ # Only show Concepts with process attr true
24
+ concepts.each do |c|
25
+ Logger.verbose ConceptStringFormatter.to_s(c) if c.process?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ require_relative '../application'
2
+ require_relative 'concept_ai_displayer'
3
+ require_relative 'code_displayer'
4
+
5
+ # Display Stats on screen.
6
+ module StatsDisplayer
7
+ def self.show(data)
8
+ return unless Application.instance.config['global']['show_mode']
9
+
10
+ # show_final_results
11
+ ConceptAIDisplayer.show(data[:concepts_ai])
12
+ CodeDisplayer.show(data[:codes_ai])
13
+ end
14
+ end
@@ -1,31 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../project'
4
3
  require_relative '../formatter/question_gift_formatter'
5
4
 
6
- # UNDER DEVELOPMENT
7
5
  # Use to export questions from Code to gift format
8
6
  module CodeGiftExporter
9
- def self.export_all(codes)
10
- codes.each do |code|
11
- code.make_questions
12
- export code
13
- end
7
+ ##
8
+ # Export an Array of codes to gift format file
9
+ # @param codes (Array)
10
+ def self.export_all(codes, file)
11
+ codes.each { |code| export(code, file) }
14
12
  end
15
13
 
16
- def self.export(code)
14
+ ##
15
+ # Export 1 code to gift format file
16
+ # @param code (Code)
17
+ def self.export(code, file)
17
18
  return false unless code.process?
18
19
 
19
- file = Project.instance.outputfile
20
20
  file.write head(code)
21
-
22
21
  code.questions.each do |question|
23
22
  file.write QuestionGiftFormatter.to_s(question)
24
23
  end
25
24
  true
26
25
  end
27
26
 
28
- def self.head(code)
27
+ private_class_method def self.head(code)
29
28
  s = "\n"
30
29
  s += '// ' + '=' * 50 + "\n"
31
30
  s += "// Code #{code.type}: #{code.filename} (#{code.questions.size})\n"
@@ -1,29 +1,41 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative '../project'
4
4
  require_relative '../formatter/question_gift_formatter'
5
5
 
6
- # Use to export data from ConceptIA to gift format
6
+ # Export ConceptIA data to gift to outputfile
7
7
  module ConceptAIGiftExporter
8
- def self.export_all(concepts_ai)
9
- concepts_ai.each { |concept_ai| export(concept_ai) }
8
+ ##
9
+ # Export an array of ConceptAI objects from Project into GIFT outpufile
10
+ # @param concepts_ai (Array)
11
+ # @param project (Project)
12
+ def self.export_all(concepts_ai, project)
13
+ concepts_ai.each { |concept_ai| export(concept_ai, project) }
10
14
  end
11
-
12
- def self.export(concept_ai)
15
+
16
+ ##
17
+ # Export 1 concept_ai from project
18
+ # @param concept_ai (ConceptAI)
19
+ # @param project (Project)
20
+ # rubocop:disable Metrics/AbcSize
21
+ private_class_method def self.export(concept_ai, project)
13
22
  return unless concept_ai.process?
14
23
 
15
- file = Project.instance.outputfile
24
+ file = project.get(:outputfile)
16
25
  file.write head(concept_ai.name)
17
-
18
- stages = Project.instance.stages
19
- stages.each_key do |stage|
26
+ Application.instance.config['questions']['stages'].each do |stage|
20
27
  concept_ai.questions[stage].each do |question|
21
28
  file.write(QuestionGiftFormatter.to_s(question))
22
29
  end
23
30
  end
24
31
  end
32
+ # rubocop:enable Metrics/AbcSize
25
33
 
26
- def self.head(name)
34
+ ##
35
+ # Convert Concept name into gift format head
36
+ # @param name (String)
37
+ # @return String
38
+ private_class_method def self.head(name)
27
39
  s = "\n"
28
40
  s += '// ' + '=' * 50 + "\n"
29
41
  s += "// Concept name: #{name}\n"
@@ -1,28 +1,30 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'yaml'
4
- require_relative '../project'
5
4
  require_relative '../formatter/question_hash_formatter'
6
5
 
7
6
  # Use to export data from ConceptIA to YAML format
8
7
  module ConceptAIYAMLExporter
9
- def self.export_all(concepts_ai)
8
+ ##
9
+ # Export array of ConceptAI objects from Project to YAML output file
10
+ # @param concepts_ai (Array)
11
+ # @param project (Project)
12
+ def self.export_all(concepts_ai, project)
10
13
  questions = []
11
14
  concepts_ai.each do |concept_ai|
12
15
  questions += get_questions_from concept_ai
13
16
  end
14
- project = Project.instance
15
17
  params = { lang: project.get(:lang) ,
16
18
  projectname: project.get(:projectname) }
17
19
  output = { params: params, questions: questions }
18
- project.yamlfile.write(output.to_yaml)
20
+ project.get(:yamlfile).write(output.to_yaml)
19
21
  end
20
22
 
21
- def self.get_questions_from(concept_ai)
23
+ private_class_method def self.get_questions_from(concept_ai)
22
24
  data = []
23
25
  return data unless concept_ai.process?
24
- stages = Project.instance.stages
25
- stages.each_key do |stage|
26
+
27
+ Application.instance.config['questions']['stages'].each do |stage|
26
28
  concept_ai.questions[stage].each do |question|
27
29
  question.lang = concept_ai.lang
28
30
  data << QuestionHashFormatter.to_hash(question)
@@ -1,21 +1,15 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require_relative '../project'
4
3
  require_relative '../formatter/concept_doc_formatter'
5
4
 
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
5
+ ##
6
+ # Export Concept to Doc file
7
+ module ConceptDocExporter
8
+ ##
9
+ # Export arrya of concepts to doc
10
+ def self.export_all(concepts, file)
11
+ concepts.each do |concept|
12
+ file.write(ConceptDocFormatter.to_s(concept)) if concept.process
18
13
  end
19
14
  end
20
-
21
15
  end
@@ -0,0 +1,18 @@
1
+ require_relative 'concept_ai_gift_exporter'
2
+ require_relative 'code_gift_exporter'
3
+ require_relative 'concept_ai_yaml_exporter'
4
+ require_relative 'concept_doc_exporter'
5
+
6
+ # Export Output data:
7
+ # * Gift (ConceptAI, Code)
8
+ # * YAML
9
+ # * Doc (txt)
10
+ module OutputFileExporter
11
+ def self.export(data, project)
12
+ ConceptAIGiftExporter.export_all(data[:concepts_ai], project)
13
+ # UNDER DEVELOPMENT
14
+ CodeGiftExporter.export_all(data[:codes_ai], project.get(:outputfile))
15
+ ConceptAIYAMLExporter.export_all(data[:concepts_ai], project)
16
+ ConceptDocExporter.export_all(data[:concepts], project.get(:lessonfile))
17
+ end
18
+ end
@@ -3,7 +3,44 @@
3
3
  ; Accept yes|no
4
4
  internet = no
5
5
 
6
+ ; Output files will be save into output folder.
7
+ outputdir = output
8
+
9
+ ; Display on screen messages about program progress
10
+ ; Accept yes|no
11
+ verbose = yes
12
+ color = yes
13
+
14
+ ; Accept resume|default
15
+ show_mode = default
16
+
17
+ [languages]
18
+ ; Default code language
19
+ default = en
20
+
21
+ ; List of code languages to be loaded
22
+ ; Accept yes|no
23
+ en = yes
24
+ es = yes
25
+ javascript = yes
26
+ math = no
27
+ python = yes
28
+ ruby = yes
29
+ sql = yes
30
+
31
+ [ai]
32
+
33
+ ; Concept formula weights to find neighbors: context, tags, tables
34
+ formula_weights = 1, 1, 1
35
+
6
36
  [questions]
37
+
38
+ ; List of values d,b,f,i,s,t
39
+ stages = d,b,f,i,s,t
40
+
41
+ ; Questions category
42
+ category =
43
+
7
44
  ; Exclude questions with this texts into their names.
8
45
  ; Accept Comma separated strings.
9
46
  exclude =
File without changes
@@ -0,0 +1,29 @@
1
+ %map{ :lang => 'en', :context => 'music, band', :version => '1'}
2
+
3
+ %concept
4
+ %names AC/DC, ACDC
5
+ %tags rock, band, australia
6
+ %def Australian rock band formed by Scottish-born brothers Malcolm and Angus Young
7
+ %table{ :fields => 'members'}
8
+ %row Bon Scott
9
+ %row Angus Young
10
+ %row Malcolm Young
11
+ %row Phil Rudd
12
+ %row Cliff Williams
13
+ %table{ :fields => 'attribute, value'}
14
+ %row
15
+ %col Genres
16
+ %col Hard rock blues rock rock and roll
17
+ %row
18
+ %col Years active
19
+ %col 1973-present
20
+ %row
21
+ %col Formed in
22
+ %col Sydney
23
+ %table{ :fields => 'Albums', :sequence => 'Albums sorted by date'}
24
+ %row Albums High Voltage
25
+ %row Powerage
26
+ %row Highway to Hell
27
+ %row Back in Black
28
+ %row Ballbreaker
29
+ %row Rock or Bust