coursegen 0.8.2 → 0.9.4

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/pr.yml +19 -0
  3. data/.gitignore +3 -0
  4. data/Gemfile.lock +78 -55
  5. data/README.md +285 -69
  6. data/Rakefile +10 -1
  7. data/coursegen.gemspec +26 -26
  8. data/lib/coursegen.rb +5 -2
  9. data/lib/coursegen/cli.rb +49 -14
  10. data/lib/coursegen/course/data/citem.rb +10 -1
  11. data/lib/coursegen/course/data/data_adaptor.rb +16 -6
  12. data/lib/coursegen/course/data/section.rb +1 -1
  13. data/lib/coursegen/course/helpers/bootstrap_markup.rb +15 -15
  14. data/lib/coursegen/course/helpers/content_helpers.rb +106 -72
  15. data/lib/coursegen/course/helpers/formatting_helpers.rb +6 -10
  16. data/lib/coursegen/course/helpers/ical_feed_helpers.rb +2 -1
  17. data/lib/coursegen/course/helpers/lecture_helpers.rb +3 -2
  18. data/lib/coursegen/course/helpers/list_of.rb +40 -20
  19. data/lib/coursegen/course/helpers/list_of_helpers.rb +20 -14
  20. data/lib/coursegen/course/helpers/logging_helpers.rb +13 -12
  21. data/lib/coursegen/course/helpers/navigation_helpers.rb +62 -23
  22. data/lib/coursegen/course/helpers/sidebar_helpers.rb +19 -18
  23. data/lib/coursegen/course/helpers/table_helpers.rb +5 -4
  24. data/lib/coursegen/course/schedule/scheduler.rb +52 -19
  25. data/lib/coursegen/templates.rb +30 -23
  26. data/lib/coursegen/version.rb +3 -1
  27. data/spec/lectures_spec.rb +60 -50
  28. data/spec/play_spec.rb +24 -12
  29. data/spec/scheduler_spec.rb +87 -27
  30. data/tech_debt.md +5 -0
  31. data/templates/Rules +14 -19
  32. data/templates/cg_config.rb +105 -21
  33. data/templates/content/bootstrap/css/custom.css +87 -151
  34. data/templates/content/bootstrap/css/full-width-pics.css +8 -64
  35. data/templates/content/bootstrap/css/postit.css +7 -0
  36. data/templates/content/bootstrap/css/toasty.css +3 -0
  37. data/templates/content/content/index.md.erb +1 -1
  38. data/templates/content/content/intro/course_toc.md.erb +0 -1
  39. data/templates/content/content/intro/welcome.md.erb +1 -3
  40. data/templates/content/content/lectures/part1/02_here_we_go.md.erb +22 -1
  41. data/templates/content/content/lectures/part2/01_start_part2.md.erb +2 -1
  42. data/templates/content/content/lectures/part2/02_continue_part2.md.erb +3 -2
  43. data/templates/layouts/banner.html.erb +4 -4
  44. data/templates/layouts/body_footer.html +3 -4
  45. data/templates/layouts/body_header.html.erb +25 -7
  46. data/templates/layouts/bottom_includes.html.erb +21 -10
  47. data/templates/layouts/course.html.erb +7 -21
  48. data/templates/layouts/helpful_box.html +1 -1
  49. data/templates/layouts/nav-menus.html.erb +16 -36
  50. data/templates/layouts/sidebar.html.erb +9 -8
  51. data/templates/layouts/slides.html.erb +69 -0
  52. data/templates/layouts/top_includes.html.erb +24 -23
  53. metadata +36 -28
  54. data/.DS_Store +0 -0
  55. data/.vscode/settings.json +0 -2
  56. data/templates/.DS_Store +0 -0
  57. data/templates/Guardfile +0 -9
  58. data/templates/content/bootstrap/css/tipuesearch.css +0 -163
  59. data/templates/content/bootstrap/js/tipuesearch.js +0 -379
  60. data/templates/content/bootstrap/js/tipuesearch.min.js +0 -12
  61. data/templates/content/bootstrap/js/tipuesearch_content.js +0 -13
  62. data/templates/content/bootstrap/js/tipuesearch_set.js +0 -23
  63. data/templates/layouts/main_navbar.html.erb +0 -21
data/Rakefile CHANGED
@@ -1 +1,10 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec'
5
+
6
+ begin
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ rescue LoadError
10
+ end
@@ -1,37 +1,37 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'coursegen/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "coursegen"
6
+ spec.name = 'coursegen'
8
7
  spec.version = Coursegen::VERSION
9
- spec.authors = ["Pito Salas"]
10
- spec.email = ["pitosalas@gmail.com"]
11
- spec.summary = "Use Nanoc to build courses and deploy them to S3"
12
- spec.description = "Use Nanoc to build courses and deploy them to S3"
13
- spec.homepage = ""
14
- spec.license = "MIT"
8
+ spec.authors = ['Pito Salas']
9
+ spec.email = ['pitosalas@gmail.com']
10
+ spec.summary = 'Use Nanoc to build courses and deploy them to S3'
11
+ spec.description = 'Use Nanoc to build courses and deploy them to S3'
12
+ spec.homepage = ''
13
+ spec.license = 'MIT'
15
14
 
16
15
  spec.files = `git ls-files -z`.split("\x0")
17
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
20
19
 
21
- spec.add_development_dependency "bundler"
22
- spec.add_development_dependency "rake"
23
-
24
- spec.add_dependency "nanoc"
25
- spec.add_dependency "thor"
26
- spec.add_dependency "rubytree"
27
- spec.add_dependency "cri"
28
- spec.add_dependency "nokogiri"
29
- spec.add_dependency "activesupport"
30
- spec.add_dependency "kramdown"
31
- spec.add_dependency "adsf"
32
- spec.add_dependency "guard"
33
- spec.add_dependency "guard-shell"
34
- spec.add_dependency "tzinfo"
35
- spec.add_dependency "icalendar"
36
- spec.add_dependency "byebug"
20
+ spec.add_development_dependency 'bundler'
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'rspec'
23
+
24
+ spec.add_dependency 'activesupport'
25
+ spec.add_dependency 'adsf'
26
+ spec.add_dependency 'byebug'
27
+ spec.add_dependency 'cri'
28
+ spec.add_dependency 'guard'
29
+ spec.add_dependency 'guard-shell'
30
+ spec.add_dependency 'icalendar'
31
+ spec.add_dependency 'kramdown'
32
+ spec.add_dependency 'nanoc'
33
+ spec.add_dependency 'nokogiri'
34
+ spec.add_dependency 'rubytree'
35
+ spec.add_dependency 'thor'
36
+ spec.add_dependency 'tzinfo'
37
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nokogiri'
2
4
 
3
5
  require 'coursegen/version'
@@ -25,7 +27,8 @@ require 'coursegen/course/helpers/list_of'
25
27
  require 'coursegen/course/helpers/ical_feed_helpers'
26
28
  require 'coursegen/course/lib/helpers_'
27
29
 
28
-
30
+ # Coursegen is a course curriculum site generator based on nanoc, with
31
+ # support for sections, lectures, code examples, homeworks, course
32
+ # calendar and lots more.
29
33
  module Coursegen
30
- # Your code goes here...
31
34
  end
@@ -1,46 +1,81 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thor'
2
4
  require 'coursegen/templates'
3
5
  require 'nanoc'
4
6
  require './cg_config.rb' if File.exist? 'cg_config.rb'
5
7
 
6
8
  module CourseGen
9
+ # Class CLI provides a command line utility for creating, building, and
10
+ # deploying a Coursegen site.
7
11
  class CLI < Thor
8
12
  include Thor::Actions
9
13
 
10
- desc "new COURSE", "Create a new course by calling nanoc. Argument is name of the COURSE"
14
+ # New creates a new nanoc site.
15
+ #
16
+ # By default, the new site does not contain any course template.
17
+ # To generate a course template within the newly created nanoc site,
18
+ # run: `cg prepare`.
19
+ #
20
+ # See: https://nanoc.ws/doc/reference/commands/#create-site
21
+ desc 'new COURSE',
22
+ 'Create a new course by calling nanoc. Argument is name of the COURSE'
11
23
  def new(course)
12
24
  run("nanoc create-site #{course}")
13
25
  end
14
26
 
15
- desc "prepare", "Update with the latest coursegen code and templates."
27
+ # Prepare generates a new course template within a nanoc site.
28
+ desc 'prepare',
29
+ 'Update with the latest coursegen code and templates.'
16
30
  def prepare
17
31
  check_valid_directory
18
32
  tplt = CourseGen::Templates.new
19
33
  tplt.generate_all
20
34
  end
21
35
 
22
- desc "compile", "build the course and put resultant site into output directory"
36
+ # Compile builds the course site and outputs it to a local directory.
37
+ #
38
+ # By default, it outputs the course site to ./output.
39
+ #
40
+ # See: https://nanoc.ws/doc/reference/commands/#compile
41
+ desc 'compile',
42
+ 'build the course and put resultant site into output directory'
23
43
  def compile
24
- run("nanoc compile")
44
+ run 'nanoc compile'
25
45
  end
26
46
 
27
- desc "serve", "start local web server to test the course web site"
47
+ # Serve starts a static web server that serves the course site.
48
+ #
49
+ # By default, the web server serves from ./output.
50
+ #
51
+ # See: https://nanoc.ws/doc/reference/commands/#view
52
+ desc 'serve',
53
+ 'start local web server to test the course web site'
28
54
  def serve
29
- run("nanoc view")
55
+ run 'nanoc view'
30
56
  end
31
57
 
32
- desc "reset", "reset all generated content to bring the course back to a base state."
58
+ # Reset removes all generated contents.
59
+ desc 'reset',
60
+ 'reset all generated content to bring the course back to a base state.'
33
61
  def reset
34
- run "rm -frd tmp"
35
- run "rm -frd output"
62
+ run 'rm -frd tmp'
63
+ run 'rm -frd output'
36
64
  end
37
65
 
38
- desc "view", "view course site locally in browser"
66
+ # View opens an browser to the running course site.
67
+ desc 'view',
68
+ 'view course site locally in browser'
39
69
  def view
40
- run "open http://0.0.0.0:3000"
70
+ run 'open http://0.0.0.0:3000'
41
71
  end
42
72
 
43
- desc "deploy", "Deploy course to S3"
73
+ # Deploy deploys the course site to AWS S3.
74
+ #
75
+ # Note: `s3cmd` needs to be properly setup before this can work. Refer
76
+ # to README.md for detailed instructions.
77
+ desc 'deploy',
78
+ 'Deploy course to S3'
44
79
  def deploy
45
80
  run "s3cmd sync --delete-removed output/ s3://#{AWS_BUCKET}/"
46
81
  end
@@ -48,9 +83,9 @@ module CourseGen
48
83
  no_commands do
49
84
  def check_valid_directory
50
85
  if CourseGen::Templates.new.valid_cg_directory?
51
- say("Valid cg directory")
86
+ say 'Valid cg directory'
52
87
  else
53
- error("Invalid cg directory")
88
+ error 'Invalid cg directory'
54
89
  end
55
90
  end
56
91
  end
@@ -6,7 +6,8 @@ require 'active_support/inflector'
6
6
  #
7
7
  class CItem
8
8
  attr_reader :order, :section, :subsection, :subsection_citem, :title,
9
- :type, :identifier, :short_name, :status, :nitem, :css_class, :homework, :desc, :cat, :assigned
9
+ :type, :identifier, :short_name, :status, :nitem, :css_class,
10
+ :homework, :hwref, :desc, :cat, :assigned, :slides, :lectref, :reading, :due
10
11
  attr_accessor :lecture_number, :lecture_date, :start_time, :end_time
11
12
 
12
13
  # Callable with nitem=nil to create a mock
@@ -53,6 +54,7 @@ class CItem
53
54
 
54
55
  def schedule_start_date_time
55
56
  return if @lecture_date.nil?
57
+
56
58
  # schedule = Toc.instance.section(@section).schedule
57
59
  # lecture_date + schedule.start_time
58
60
  lecture_date + @start_time
@@ -60,6 +62,7 @@ class CItem
60
62
 
61
63
  def schedule_end_date_time
62
64
  return if @lecture_date.nil?
65
+
63
66
  # schedule = Toc.instance.section(@section).schedule
64
67
  # lecture_date + schedule.end_time
65
68
  lecture_date + @end_time
@@ -85,7 +88,13 @@ class CItem
85
88
  @homework = @nitem[:homework]
86
89
  @desc = @nitem[:desc]
87
90
  @cat = @nitem[:cat]
91
+ @hwref = @nitem[:hwref]
88
92
  @assigned = @nitem[:assigned]
93
+ @slides = @nitem[:slides]
94
+ @lectref = @nitem[:lectref]
95
+ @reading = @nitem[:reading]
96
+ @due = @nitem[:due]
97
+
89
98
  end
90
99
 
91
100
  def parse_identifier(ident)
@@ -5,8 +5,8 @@ class DataAdaptor
5
5
  end
6
6
 
7
7
  # column_selector is one of: :number, :date, :title, :homework
8
- COL_NAMES = {number: "#", date: "lecture date", title: "title",
9
- homework: "homework", desc: "description", cat: "category"}
8
+ COL_NAMES = { number: '#', date: 'lecture date', title: 'title',
9
+ homework: 'homework', desc: 'description', cat: 'category', hwref: 'homework', lectref: 'topics', reading: 'reading' }
10
10
 
11
11
  def column_name(column_selector)
12
12
  COL_NAMES[column_selector]
@@ -30,6 +30,8 @@ class DataAdaptor
30
30
  citem.identifier
31
31
  when :desc
32
32
  citem.desc
33
+ when :due
34
+ citem.due
33
35
  when :homework
34
36
  citem.homework
35
37
  when :assigned
@@ -39,13 +41,21 @@ class DataAdaptor
39
41
  when :end_date_time
40
42
  citem.schedule_end_date_time
41
43
  when :full_desc
42
- desc = citem.desc || ""
43
- hw = citem.homework || ""
44
- desc + ". HW: " + hw
44
+ desc = citem.desc || ''
45
+ hw = citem.homework || ''
46
+ desc + '. HW: ' + hw
45
47
  when :cat
46
48
  citem.cat
49
+ when :lectref
50
+ citem.lectref
51
+ when :hwref
52
+ citem.hwref
53
+ when :reading
54
+ citem.reading
55
+ when :order
56
+ citem.order
47
57
  else
48
- "error!"
58
+ 'error!'
49
59
  end
50
60
  end
51
61
  end
@@ -60,7 +60,7 @@ class Section
60
60
  def lookup_citem_by_identifier identifier
61
61
  res = @citems.select { |i| i.identifier.to_s == identifier }
62
62
  fail "TOC#lookup_citem_by_identifier failed to find: '#{identifier}'" if res.length != 1
63
- # binding.pry if res.length != 1
63
+ byebug if res.length != 1
64
64
  res[0]
65
65
  end
66
66
 
@@ -1,32 +1,32 @@
1
+ # Class BootstrapMarkup provides methods for using Bootstrap specific HTML
2
+ # markups.
1
3
  class BootstrapMarkup
2
4
  def initialize
3
- @str = ""
5
+ @str = ''
4
6
  end
5
7
 
6
- def table_begin(css_class = "table-condensed")
7
- puts css_class.class
8
+ def table_begin(css_class = 'table-condensed')
8
9
  @str << "<table class=\"table x #{css_class}\">"
9
- puts @str
10
10
  end
11
11
 
12
12
  def table_end
13
- @str << "</table>"
13
+ @str << '</table>'
14
14
  end
15
15
 
16
16
  def headers_begin
17
- @str << "<thead><tr>"
17
+ @str << '<thead><tr>'
18
18
  end
19
19
 
20
20
  def headers_end
21
- @str << "</tr></thead>"
21
+ @str << '</tr></thead>'
22
22
  end
23
23
 
24
24
  def header_begin
25
- @str << "<th>"
25
+ @str << '<th>'
26
26
  end
27
27
 
28
28
  def header_end
29
- @str << "</th>"
29
+ @str << '</th>'
30
30
  end
31
31
 
32
32
  def header_content(str)
@@ -34,27 +34,27 @@ class BootstrapMarkup
34
34
  end
35
35
 
36
36
  def row_begin
37
- @str << "<tr>"
37
+ @str << '<tr>'
38
38
  end
39
39
 
40
40
  def row_end
41
- @str << "</tr>"
41
+ @str << '</tr>'
42
42
  end
43
43
 
44
44
  def cell_begin
45
- @str << "<td>"
45
+ @str << '<td>'
46
46
  end
47
47
 
48
48
  def cell_end
49
- @str << "</td>"
49
+ @str << '</td>'
50
50
  end
51
51
 
52
52
  def bigcell_begin
53
- @str << "<td colspan=\"3\"><h5>"
53
+ @str << '<td colspan="3"><h5>'
54
54
  end
55
55
 
56
56
  def bigcell_end
57
- @str << "</h5></td>"
57
+ @str << '</h5></td>'
58
58
  end
59
59
 
60
60
  def cell_content(str)
@@ -1,23 +1,22 @@
1
- # Helpers to be used to annotate content
2
- require 'byebug'
1
+ # ContentHelpers is used to annotate content.
3
2
  module ContentHelpers
4
3
  def include_topic(item_symbol)
5
- incorporated_topic = lookup_nitem("topics", item_symbol.to_s)
4
+ incorporated_topic = lookup_nitem('topics', item_symbol.to_s)
6
5
  items[incorporated_topic.identifier.to_s].compiled_content
7
6
  end
8
7
 
9
8
  def include_page(item_symbol)
10
- incorporated_topic = lookup_nitem("pages", item_symbol.to_s)
9
+ incorporated_topic = lookup_nitem('pages', item_symbol.to_s)
11
10
  items[incorporated_topic.identifier.to_s].compiled_content
12
11
  end
13
12
 
14
13
  def include_background(item_symbol)
15
- incorporated_topic = lookup_nitem("background", item_symbol.to_s)
14
+ incorporated_topic = lookup_nitem('background', item_symbol.to_s)
16
15
  items[incorporated_topic.identifier.to_s].compiled_content
17
16
  end
18
17
 
19
18
  def include_intro(item_symbol)
20
- incorporated_topic = lookup_nitem("intro", item_symbol.to_s)
19
+ incorporated_topic = lookup_nitem('intro', item_symbol.to_s)
21
20
  items[incorporated_topic.identifier.to_s].compiled_content
22
21
  end
23
22
 
@@ -47,69 +46,95 @@ module ContentHelpers
47
46
  " *#{string}*{: style=\"color: red\"} "
48
47
  end
49
48
 
50
- def ir(string); italic_red(string); end
49
+ def ir(string)
50
+ italic_red(string)
51
+ end
51
52
 
52
- def callout_1(title, body)
53
+ def callout1(title, body)
53
54
  <<~HTMLSTRING
54
- <div class="well well-sm">
55
+ <div class="well well-sm callout">
55
56
  <span class="themebg label label-primary">#{title}</span>#{body}
56
57
  </div>
57
58
  HTMLSTRING
58
59
  end
59
60
 
60
- def callout(title, body)
61
+ def callout2(title, body)
61
62
  <<~HTMLSTRING
62
- <div class="border border-primary rounded p-2 m-3">
63
+ <div class="callout border border-primary rounded p-2 m-3">
63
64
  <span class="badge badge-pill badge-primary">#{title}</span>#{body}
64
65
  </div>
65
66
  HTMLSTRING
66
67
  end
67
68
 
69
+ def callout(title, body, style=:big)
70
+ if (style == :big)
71
+ %(<div class="jumbotron py-1 border border-primary border-rounded-lg">
72
+ <h1 class="display-5">#{title}</h1>
73
+ <p class="lead">#{body}</p></div>)
74
+ elsif (style == :small)
75
+ <<~HTMLSTRING
76
+ <div class="callout border border-primary rounded p-2 m-3">
77
+ <span class="badge badge-pill badge-primary">#{title}</span>#{body}
78
+ </div>
79
+ HTMLSTRING
80
+ else
81
+ "error in callout call #{style}"
82
+ end
83
+ end
84
+
85
+ def iconbadge1(icon, tooltip)
86
+ %(<img src="/bootstrap/bootstrap-icons-1.0.0/#{icon}.svg" title="#{tooltip}" class="iconbadge">)
87
+ end
88
+
89
+ def iconbadge(icon, tooltip)
90
+ %(<svg class="bi iconbadge" title="#{tooltip}" data-placement="top" data-title="#{tooltip}" data-toggle="tooltip" fill="blue"><use xlink:href="/bootstrap/bootstrap-icons-1.0.0/bootstrap-icons.svg##{icon}"/></svg>)
91
+ end
92
+
68
93
  def textbadge(text, tooltip)
69
94
  %(<span class="label label-info" data-toggle="tooltip" data-placement="top" title="#{tooltip}">#{text}</span>)
70
95
  end
71
96
 
72
- def iconbadge(icon, tooltip)
97
+ def iconbadge2(icon, tooltip)
73
98
  %(<span class="fas fa-#{icon} themefg" data-toggle="tooltip" data-placement="top" title="#{tooltip}"></span>)
74
99
  end
75
100
 
76
101
  def pdfbadge
77
- iconbadge("file-pdf", "Submit as 1 page pdf, include name and homework #")
102
+ iconbadge('file-earmark-richtext-fill', 'Submit a pdf file')
78
103
  end
79
104
 
80
105
  def codebadge
81
- iconbadge("code", "Work on code in your portfolio")
106
+ iconbadge('file-code-fill', 'Work on code in your portfolio')
82
107
  end
83
108
 
84
109
  def cloudbadge
85
- iconbadge("cloud-upload-alt", "Work on code in your portfolio")
110
+ iconbadge('cloud-fill', 'Work on code in your portfolio')
86
111
  end
87
112
 
88
113
  def zipbadge
89
- iconbadge("briefcase", "Submit work as an attachment")
114
+ iconbadge('file-earmark-zip-fill', 'Submit work as an attachment')
90
115
  end
91
116
 
92
117
  def partbadge
93
- iconbadge("hand-peace", "Graded for participation only - pass/fail")
118
+ iconbadge('heart-half', 'Graded for participation only - pass/fail')
94
119
  end
95
120
 
96
121
  def timebadge
97
- iconbadge("coffee", "Must be submitted first thing on day of class")
122
+ iconbadge('alarm-fill', 'Must be submitted first thing on day of class')
98
123
  end
99
124
 
100
125
  def teambadge
101
- iconbadge("handshake", "Team Deliverable")
126
+ iconbadge('people-fill', 'Team Deliverable')
102
127
  end
103
128
 
104
129
  def include_image_old(filename_string, extra_class: nil)
105
- css_class = "img-responsive"
106
- css_class += " img-" + extra_class unless extra_class.nil?
130
+ css_class = 'img-responsive'
131
+ css_class += ' img-' + extra_class unless extra_class.nil?
107
132
  <<-HTMLSTRING
108
133
  <img src="#{filename_string}" class=\"%s\" />" % css_class
109
134
  HTMLSTRING
110
135
  end
111
136
 
112
- def include_image(filename_string, extra: "")
137
+ def include_image(filename_string, extra: '')
113
138
  <<~HTMLSTRING
114
139
  <div class="row">
115
140
  <div class="col-md-offset-2 col-md-8">
@@ -119,13 +144,13 @@ module ContentHelpers
119
144
  HTMLSTRING
120
145
  end
121
146
 
122
- def image(filename_string, extra: "")
123
- <<-HTMLSTRING
124
- <img src="/content/topics/images/#{filename_string}" class="img-responsive img-thumbnail" #{extra}/>
147
+ def image(filename_string, extra: '')
148
+ <<~HTMLSTRING
149
+ <img src="/content/topics/images/#{filename_string}" class="img-responsive img-thumbnail" #{extra}/>
125
150
  HTMLSTRING
126
151
  end
127
152
 
128
- def important(string = ":")
153
+ def important(string = ':')
129
154
  <<-HTMLSTRING
130
155
  <div class="cg-important">
131
156
  #{string}
@@ -133,26 +158,26 @@ module ContentHelpers
133
158
  HTMLSTRING
134
159
  end
135
160
 
136
- def nb(string = ":")
161
+ def nb(string = ':')
137
162
  <<-HTMLSTRING
138
163
  <div class="label label-info">#{string}</div>
139
164
  HTMLSTRING
140
165
  end
141
166
 
142
- def tbd(string = "")
167
+ def tbd(string = '')
143
168
  "*[TO BE DETERMINED#{string}]*{: style=\"color: red\"}"
144
169
  end
145
170
 
146
- def deliverable(string, append = "")
171
+ def deliverable(string, append = '')
147
172
  "*Deliverable:*{: style=\"color: red\"} #{string + append} "
148
173
  end
149
174
 
150
175
  def deliverable_po(string)
151
- deliverable(string, " *(graded for participation only)*")
176
+ deliverable(string, ' *(graded for participation only)*')
152
177
  end
153
178
 
154
179
  def deliverable_popdf(string)
155
- deliverable(string, " *(pdf with name and hw number, graded for participation only)*")
180
+ deliverable(string, ' *(pdf with name and hw number, graded for participation only)*')
156
181
  end
157
182
 
158
183
  def team_deliverable(string)
@@ -168,7 +193,7 @@ module ContentHelpers
168
193
  end
169
194
 
170
195
  def homework_hdr(show_legend: :on)
171
- body = "#### Homework due for today"
196
+ body = '## Homework due for today'
172
197
  legend = "\n**Legend**: #{partbadge}: Participation (pass/fail) | #{pdfbadge}: PDF | #{teambadge}: Team | #{zipbadge}: Attachment"
173
198
  body += legend if show_legend == :on
174
199
  body
@@ -185,8 +210,8 @@ module ContentHelpers
185
210
  # body << %(" class="img-polaroid" alt=""></div>)
186
211
  # counter += 1
187
212
  # end
188
- # body << %(</div> <a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>
189
- # <a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>
213
+ # body << %(</div> <a class="left carousel-control" href="#myCarousel" data-slide="prev"></a>
214
+ # <a class="right carousel-control" href="#myCarousel" data-slide="next"></a>
190
215
  # </div>)
191
216
  # body
192
217
  # end
@@ -219,34 +244,33 @@ module ContentHelpers
219
244
  # body
220
245
  # end
221
246
 
222
- def carousel_V4(filenames)
247
+ def carousel_v4(filenames)
223
248
  body = <<~HEREDOC
224
- <div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
225
- <div class="carousel-inner">
249
+ <div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
250
+ <div class="carousel-inner">
226
251
  HEREDOC
227
252
  count = 0
228
253
  filenames.each do |fname|
229
- active = count == 0 ? "active" : ""
254
+ active = count == 0 ? 'active' : ''
230
255
  body << <<~HEREDOC
231
- <div class="carousel-item #{active}">
232
- <img class="d-block w-100" src="/content/topics/images/#{fname}">
233
- </div>
256
+ <div class="carousel-item #{active}">
257
+ <img class="d-block w-80" src="/content/topics/images/#{fname}">
258
+ </div>
234
259
  HEREDOC
235
260
  count += 1
236
261
  end
237
262
  body << <<~HEREDOC
263
+ </div>
264
+ <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
265
+ <span class="carousel-control-prev-icon" aria-hidden="true"></span>
266
+ <span class="sr-only">Previous</span>
267
+ </a>
268
+ <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
269
+ <span class="carousel-control-next-icon" aria-hidden="true"></span>
270
+ <span class="sr-only">Next</span>
271
+ </a>
238
272
  </div>
239
- <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
240
- <span class="carousel-control-prev-icon" aria-hidden="true"></span>
241
- <span class="sr-only">Previous</span>
242
- </a>
243
- <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
244
- <span class="carousel-control-next-icon" aria-hidden="true"></span>
245
- <span class="sr-only">Next</span>
246
- </a>
247
- </div>
248
273
  HEREDOC
249
- puts body
250
274
  body
251
275
  end
252
276
 
@@ -275,13 +299,13 @@ module ContentHelpers
275
299
  end
276
300
 
277
301
  def include_ruby(name)
278
- filename = Dir.pwd + "/content/content/topics/scripts/" + name.to_s + ".rb"
302
+ filename = Dir.pwd + '/content/content/topics/scripts/' + name.to_s + '.rb'
279
303
  filecontents = File.new(filename).read
280
304
  ruby_string filecontents
281
305
  end
282
306
 
283
307
  def include_python(name)
284
- filename = Dir.pwd + "/content/content/topics/robotcode/" + name.to_s + ".py"
308
+ filename = Dir.pwd + '/content/content/topics/robotcode/' + name.to_s + '.py'
285
309
  filecontents = File.new(filename).read
286
310
  ruby_string filecontents
287
311
  end
@@ -290,11 +314,9 @@ module ContentHelpers
290
314
  "\n~~~~~~"
291
315
  end
292
316
 
293
- def code_end(lang = "")
317
+ def code_end(lang = '')
294
318
  str = "~~~~~~\n"
295
- if ["ruby", "css", "java", "html"].include? lang
296
- str += "{: .language-#{lang}}"
297
- end
319
+ str += "{: .language-#{lang}}" if %w[ruby css java html].include? lang
298
320
  str
299
321
  end
300
322
 
@@ -303,52 +325,64 @@ module ContentHelpers
303
325
  end
304
326
 
305
327
  def include_code(name)
306
- filename = Dir.pwd + "/content/content/topics/scripts/" + name
328
+ filename = Dir.pwd + '/content/content/topics/scripts/' + name
307
329
  filecontents = File.new(filename).read
308
330
  code_string filecontents
309
331
  end
310
332
 
311
- def postit_begin title
312
- "<div class=\"postit\">" + "<h5>" + title + "</h5>"
333
+ def source_begin(language)
334
+ "<pre class=\"#{language}\">"
335
+ end
336
+
337
+ def source_end
338
+ '</pre>'
339
+ end
340
+
341
+ def postit_begin(title)
342
+ '<div class="postit">' + '<h5>' + title + '</h5>'
313
343
  end
314
344
 
315
345
  def postit_end
316
- "</div>"
346
+ '</div>'
317
347
  end
318
348
 
319
349
  def ul_begin
320
- "<ul>"
350
+ '<ul>'
321
351
  end
322
352
 
323
353
  def ul_end
324
- "</ul>"
354
+ '</ul>'
325
355
  end
326
356
 
327
- def ul body
357
+ def ul(body)
328
358
  "<ul>#{body}</ul>"
329
359
  end
330
360
 
331
- def list_items *items
332
- items.reduce("") do |s, i|
333
- if i.start_with?("<ul>")
361
+ def slide
362
+ '<slide_break></slide_break>'
363
+ end
364
+
365
+ def list_items(*items)
366
+ items.reduce('') do |s, i|
367
+ if i.start_with?('<ul>')
334
368
  s + i
335
369
  else
336
- s + "<li>" + i + "</li>"
370
+ s + '<li>' + i + '</li>'
337
371
  end
338
372
  end
339
373
  end
340
374
 
341
375
  def lab_note(title)
342
- "<h5 style=\"font-family:'Permanent Marker'; font-szie:18px; color: red;\">#{title}</h5>"
376
+ "<h3 style=\"font-family:'Permanent Marker'; font-szie:18px; color: red;\">#{title}</h3>"
343
377
  end
344
378
 
345
379
  def toasty(header, *items)
346
- str = %Q(<div class="border border-info rounded w-75 mx-auto p-2 m-3">
380
+ str = %(<div class="border border-info rounded w-75 mx-auto p-2 m-3">
347
381
  <h5>#{header}</h5><ul>)
348
382
  items.each do |itm|
349
- str += "<li>" + itm + "</li>"
383
+ str += '<li>' + itm + '</li>'
350
384
  end
351
- str += "</ul></div>"
385
+ str += '</ul></div>'
352
386
  str
353
387
  end
354
388
  end