coursegen 0.7.7 → 0.9.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 +4 -4
- data/.github/workflows/pr.yml +19 -0
- data/.gitignore +3 -0
- data/Gemfile.lock +90 -45
- data/README.md +285 -69
- data/Rakefile +10 -1
- data/coursegen.gemspec +26 -26
- data/lib/coursegen.rb +5 -2
- data/lib/coursegen/cli.rb +49 -14
- data/lib/coursegen/course/data/citem.rb +10 -1
- data/lib/coursegen/course/data/data_adaptor.rb +16 -6
- data/lib/coursegen/course/data/section.rb +1 -1
- data/lib/coursegen/course/helpers/bootstrap_markup.rb +15 -15
- data/lib/coursegen/course/helpers/content_helpers.rb +173 -100
- data/lib/coursegen/course/helpers/formatting_helpers.rb +6 -10
- data/lib/coursegen/course/helpers/ical_feed_helpers.rb +2 -1
- data/lib/coursegen/course/helpers/lecture_helpers.rb +3 -2
- data/lib/coursegen/course/helpers/list_of.rb +40 -20
- data/lib/coursegen/course/helpers/list_of_helpers.rb +20 -14
- data/lib/coursegen/course/helpers/logging_helpers.rb +13 -12
- data/lib/coursegen/course/helpers/navigation_helpers.rb +63 -20
- data/lib/coursegen/course/helpers/sidebar_helpers.rb +19 -18
- data/lib/coursegen/course/helpers/table_helpers.rb +5 -4
- data/lib/coursegen/course/schedule/scheduler.rb +52 -19
- data/lib/coursegen/templates.rb +30 -23
- data/lib/coursegen/version.rb +3 -1
- data/spec/lectures_spec.rb +60 -50
- data/spec/play_spec.rb +24 -12
- data/spec/scheduler_spec.rb +87 -27
- data/tech_debt.md +5 -0
- data/templates/Rules +14 -19
- data/templates/cg_config.rb +105 -21
- data/templates/content/bootstrap/css/custom.css +87 -151
- data/templates/content/bootstrap/css/full-width-pics.css +8 -64
- data/templates/content/bootstrap/css/postit.css +7 -0
- data/templates/content/bootstrap/css/toasty.css +3 -0
- data/templates/content/content/index.md.erb +1 -1
- data/templates/content/content/intro/course_toc.md.erb +0 -1
- data/templates/content/content/intro/welcome.md.erb +1 -3
- data/templates/content/content/lectures/part1/02_here_we_go.md.erb +22 -1
- data/templates/content/content/lectures/part2/01_start_part2.md.erb +2 -1
- data/templates/content/content/lectures/part2/02_continue_part2.md.erb +3 -2
- data/templates/layouts/banner.html.erb +4 -4
- data/templates/layouts/body_footer.html +3 -4
- data/templates/layouts/body_header.html.erb +25 -7
- data/templates/layouts/bottom_includes.html.erb +21 -10
- data/templates/layouts/course.html.erb +7 -21
- data/templates/layouts/helpful_box.html +1 -1
- data/templates/layouts/nav-menus.html.erb +16 -36
- data/templates/layouts/sidebar.html.erb +9 -8
- data/templates/layouts/slides.html.erb +69 -0
- data/templates/layouts/top_includes.html.erb +24 -23
- metadata +33 -24
- data/.DS_Store +0 -0
- data/templates/.DS_Store +0 -0
- data/templates/Guardfile +0 -9
- data/templates/content/bootstrap/css/tipuesearch.css +0 -163
- data/templates/content/bootstrap/js/tipuesearch.js +0 -379
- data/templates/content/bootstrap/js/tipuesearch.min.js +0 -12
- data/templates/content/bootstrap/js/tipuesearch_content.js +0 -13
- data/templates/content/bootstrap/js/tipuesearch_set.js +0 -23
- data/templates/layouts/main_navbar.html.erb +0 -21
data/Rakefile
CHANGED
data/coursegen.gemspec
CHANGED
@@ -1,37 +1,37 @@
|
|
1
|
-
|
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 =
|
6
|
+
spec.name = 'coursegen'
|
8
7
|
spec.version = Coursegen::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
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 = [
|
18
|
+
spec.require_paths = ['lib']
|
20
19
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
|
24
|
-
|
25
|
-
spec.add_dependency
|
26
|
-
spec.add_dependency
|
27
|
-
spec.add_dependency
|
28
|
-
spec.add_dependency
|
29
|
-
spec.add_dependency
|
30
|
-
spec.add_dependency
|
31
|
-
spec.add_dependency
|
32
|
-
spec.add_dependency
|
33
|
-
spec.add_dependency
|
34
|
-
spec.add_dependency
|
35
|
-
spec.add_dependency
|
36
|
-
spec.add_dependency
|
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
|
data/lib/coursegen.rb
CHANGED
@@ -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
|
data/lib/coursegen/cli.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
44
|
+
run 'nanoc compile'
|
25
45
|
end
|
26
46
|
|
27
|
-
|
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
|
55
|
+
run 'nanoc view'
|
30
56
|
end
|
31
57
|
|
32
|
-
|
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
|
35
|
-
run
|
62
|
+
run 'rm -frd tmp'
|
63
|
+
run 'rm -frd output'
|
36
64
|
end
|
37
65
|
|
38
|
-
|
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
|
70
|
+
run 'open http://0.0.0.0:3000'
|
41
71
|
end
|
42
72
|
|
43
|
-
|
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
|
86
|
+
say 'Valid cg directory'
|
52
87
|
else
|
53
|
-
error
|
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,
|
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:
|
9
|
-
homework:
|
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 +
|
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
|
-
|
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
|
-
|
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 =
|
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 <<
|
13
|
+
@str << '</table>'
|
14
14
|
end
|
15
15
|
|
16
16
|
def headers_begin
|
17
|
-
@str <<
|
17
|
+
@str << '<thead><tr>'
|
18
18
|
end
|
19
19
|
|
20
20
|
def headers_end
|
21
|
-
@str <<
|
21
|
+
@str << '</tr></thead>'
|
22
22
|
end
|
23
23
|
|
24
24
|
def header_begin
|
25
|
-
@str <<
|
25
|
+
@str << '<th>'
|
26
26
|
end
|
27
27
|
|
28
28
|
def header_end
|
29
|
-
@str <<
|
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 <<
|
37
|
+
@str << '<tr>'
|
38
38
|
end
|
39
39
|
|
40
40
|
def row_end
|
41
|
-
@str <<
|
41
|
+
@str << '</tr>'
|
42
42
|
end
|
43
43
|
|
44
44
|
def cell_begin
|
45
|
-
@str <<
|
45
|
+
@str << '<td>'
|
46
46
|
end
|
47
47
|
|
48
48
|
def cell_end
|
49
|
-
@str <<
|
49
|
+
@str << '</td>'
|
50
50
|
end
|
51
51
|
|
52
52
|
def bigcell_begin
|
53
|
-
@str <<
|
53
|
+
@str << '<td colspan="3"><h5>'
|
54
54
|
end
|
55
55
|
|
56
56
|
def bigcell_end
|
57
|
-
@str <<
|
57
|
+
@str << '</h5></td>'
|
58
58
|
end
|
59
59
|
|
60
60
|
def cell_content(str)
|
@@ -1,23 +1,22 @@
|
|
1
|
-
#
|
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(
|
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(
|
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(
|
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(
|
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,77 +46,101 @@ module ContentHelpers
|
|
47
46
|
" *#{string}*{: style=\"color: red\"} "
|
48
47
|
end
|
49
48
|
|
50
|
-
def ir(string)
|
49
|
+
def ir(string)
|
50
|
+
italic_red(string)
|
51
|
+
end
|
52
|
+
|
53
|
+
def callout_1(title, body)
|
54
|
+
<<~HTMLSTRING
|
55
|
+
<div class="well well-sm callout">
|
56
|
+
<span class="themebg label label-primary">#{title}</span>#{body}
|
57
|
+
</div>
|
58
|
+
HTMLSTRING
|
59
|
+
end
|
60
|
+
|
61
|
+
def callout_2(title, body)
|
62
|
+
<<~HTMLSTRING
|
63
|
+
<div class="callout border border-primary rounded p-2 m-3">
|
64
|
+
<span class="badge badge-pill badge-primary">#{title}</span>#{body}
|
65
|
+
</div>
|
66
|
+
HTMLSTRING
|
67
|
+
end
|
51
68
|
|
52
69
|
def callout(title, body)
|
53
|
-
|
54
|
-
<
|
55
|
-
<
|
56
|
-
</div>
|
57
|
-
HTMLSTRING
|
70
|
+
%(<div class="jumbotron py-1 border border-primary border-rounded-lg">
|
71
|
+
<h1 class="display-5">#{title}</h1>
|
72
|
+
<p class="lead">#{body}</p></div>)
|
58
73
|
end
|
59
74
|
|
75
|
+
def iconbadge1(icon, tooltip)
|
76
|
+
%(<img src="/bootstrap/bootstrap-icons-1.0.0/#{icon}.svg" title="#{tooltip}" class="iconbadge">)
|
77
|
+
end
|
78
|
+
|
79
|
+
def iconbadge(icon, tooltip)
|
80
|
+
%(<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>)
|
81
|
+
end
|
82
|
+
|
60
83
|
def textbadge(text, tooltip)
|
61
84
|
%(<span class="label label-info" data-toggle="tooltip" data-placement="top" title="#{tooltip}">#{text}</span>)
|
62
85
|
end
|
63
86
|
|
64
|
-
def
|
65
|
-
%(<span class="
|
87
|
+
def iconbadge2(icon, tooltip)
|
88
|
+
%(<span class="fas fa-#{icon} themefg" data-toggle="tooltip" data-placement="top" title="#{tooltip}"></span>)
|
66
89
|
end
|
67
90
|
|
68
91
|
def pdfbadge
|
69
|
-
iconbadge(
|
92
|
+
iconbadge('file-earmark-richtext-fill', 'Submit a pdf file')
|
70
93
|
end
|
71
94
|
|
72
95
|
def codebadge
|
73
|
-
iconbadge(
|
96
|
+
iconbadge('file-code-fill', 'Work on code in your portfolio')
|
74
97
|
end
|
75
98
|
|
76
99
|
def cloudbadge
|
77
|
-
|
100
|
+
iconbadge('cloud-fill', 'Work on code in your portfolio')
|
78
101
|
end
|
79
102
|
|
80
103
|
def zipbadge
|
81
|
-
iconbadge(
|
104
|
+
iconbadge('file-earmark-zip-fill', 'Submit work as an attachment')
|
82
105
|
end
|
83
106
|
|
84
107
|
def partbadge
|
85
|
-
iconbadge(
|
108
|
+
iconbadge('heart-half', 'Graded for participation only - pass/fail')
|
86
109
|
end
|
87
110
|
|
88
111
|
def timebadge
|
89
|
-
iconbadge(
|
112
|
+
iconbadge('alarm-fill', 'Must be submitted first thing on day of class')
|
90
113
|
end
|
91
114
|
|
92
115
|
def teambadge
|
93
|
-
iconbadge(
|
116
|
+
iconbadge('people-fill', 'Team Deliverable')
|
94
117
|
end
|
95
118
|
|
96
119
|
def include_image_old(filename_string, extra_class: nil)
|
97
|
-
css_class =
|
98
|
-
css_class +=
|
120
|
+
css_class = 'img-responsive'
|
121
|
+
css_class += ' img-' + extra_class unless extra_class.nil?
|
99
122
|
<<-HTMLSTRING
|
100
123
|
<img src="#{filename_string}" class=\"%s\" />" % css_class
|
101
124
|
HTMLSTRING
|
102
125
|
end
|
103
126
|
|
104
|
-
def include_image(filename_string, extra:
|
105
|
-
|
106
|
-
<div class="row">
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
</div>
|
111
|
-
|
127
|
+
def include_image(filename_string, extra: '')
|
128
|
+
<<~HTMLSTRING
|
129
|
+
<div class="row">
|
130
|
+
<div class="col-md-offset-2 col-md-8">
|
131
|
+
<img src="#{filename_string}" class="img-responsive img-thumbnail" #{extra}/>
|
132
|
+
</div>
|
133
|
+
</div>
|
134
|
+
HTMLSTRING
|
112
135
|
end
|
113
136
|
|
114
|
-
def image(filename_string, extra:
|
115
|
-
|
116
|
-
|
137
|
+
def image(filename_string, extra: '')
|
138
|
+
<<~HTMLSTRING
|
139
|
+
<img src="/content/topics/images/#{filename_string}" class="img-responsive img-thumbnail" #{extra}/>
|
117
140
|
HTMLSTRING
|
118
141
|
end
|
119
142
|
|
120
|
-
def important(string =
|
143
|
+
def important(string = ':')
|
121
144
|
<<-HTMLSTRING
|
122
145
|
<div class="cg-important">
|
123
146
|
#{string}
|
@@ -125,26 +148,26 @@ HTMLSTRING
|
|
125
148
|
HTMLSTRING
|
126
149
|
end
|
127
150
|
|
128
|
-
def nb(string =
|
151
|
+
def nb(string = ':')
|
129
152
|
<<-HTMLSTRING
|
130
153
|
<div class="label label-info">#{string}</div>
|
131
154
|
HTMLSTRING
|
132
155
|
end
|
133
156
|
|
134
|
-
def tbd(string =
|
157
|
+
def tbd(string = '')
|
135
158
|
"*[TO BE DETERMINED#{string}]*{: style=\"color: red\"}"
|
136
159
|
end
|
137
160
|
|
138
|
-
def deliverable(string, append =
|
161
|
+
def deliverable(string, append = '')
|
139
162
|
"*Deliverable:*{: style=\"color: red\"} #{string + append} "
|
140
163
|
end
|
141
164
|
|
142
165
|
def deliverable_po(string)
|
143
|
-
deliverable(string,
|
166
|
+
deliverable(string, ' *(graded for participation only)*')
|
144
167
|
end
|
145
168
|
|
146
169
|
def deliverable_popdf(string)
|
147
|
-
deliverable(string,
|
170
|
+
deliverable(string, ' *(pdf with name and hw number, graded for participation only)*')
|
148
171
|
end
|
149
172
|
|
150
173
|
def team_deliverable(string)
|
@@ -160,54 +183,84 @@ HTMLSTRING
|
|
160
183
|
end
|
161
184
|
|
162
185
|
def homework_hdr(show_legend: :on)
|
163
|
-
body =
|
186
|
+
body = '## Homework due for today'
|
164
187
|
legend = "\n**Legend**: #{partbadge}: Participation (pass/fail) | #{pdfbadge}: PDF | #{teambadge}: Team | #{zipbadge}: Attachment"
|
165
188
|
body += legend if show_legend == :on
|
166
189
|
body
|
167
190
|
end
|
168
191
|
|
169
|
-
def carousel(filenames)
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
192
|
+
# def carousel(filenames)
|
193
|
+
# body = %(<div id="myCarousel" class="carousel slide" style="width: 500px; margin: 0 auto;">
|
194
|
+
# <div class="carousel-inner" style="margin: 20px; ">)
|
195
|
+
# counter = 0
|
196
|
+
# filenames.each do |nam|
|
197
|
+
# body << counter == 0 ? %(div class="item active">) : body << %(<div class="item">~
|
198
|
+
# body << %~<img src=")
|
199
|
+
# body << "/content/images/#{nam}"
|
200
|
+
# body << %(" class="img-polaroid" alt=""></div>)
|
201
|
+
# counter += 1
|
202
|
+
# end
|
203
|
+
# body << %(</div> <a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>
|
204
|
+
# <a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>
|
205
|
+
# </div>)
|
206
|
+
# body
|
207
|
+
# end
|
208
|
+
|
209
|
+
# def carousel_new(filenames)
|
210
|
+
# carousel_work(filenames.map { |filename| "/content/topics/images/" + filename })
|
211
|
+
# end
|
212
|
+
|
213
|
+
# def carousel_work(filenames)
|
214
|
+
# body = %(<div id="myCarousel" class="carousel slide" data-ride="carousel" style="width: 500px; margin: 0 auto;">
|
215
|
+
# <div class="carousel-inner" role="listbox" style="margin: 20px; ">)
|
216
|
+
# counter = 0
|
217
|
+
# filenames.each do |nam|
|
218
|
+
# ci = counter == 0 ? %(<div class="item active">) : %(<div class="item">)
|
219
|
+
# body << ci
|
220
|
+
# body << %(<img src=")
|
221
|
+
# body << nam
|
222
|
+
# body << %("/>"></div>)
|
223
|
+
# counter += 1
|
224
|
+
# end
|
225
|
+
# body << %(</div> <a class="left carousel-control" role="button" href="#myCarousel" data-slide="prev">
|
226
|
+
# <span class="glyphicon glyphicon-chevron-left"></span>
|
227
|
+
# <span class="sr-only">Previous</span>
|
228
|
+
# </a>
|
229
|
+
# <a class="right carousel-control" role="button" href="#myCarousel" data-slide="next">
|
230
|
+
# <span class="glyphicon glyphicon-chevron-right"></span>
|
231
|
+
# <span class="sr-only">Next</span>
|
232
|
+
# </a>
|
233
|
+
# </div>)
|
234
|
+
# body
|
235
|
+
# end
|
236
|
+
|
237
|
+
def carousel_V4(filenames)
|
238
|
+
body = <<~HEREDOC
|
239
|
+
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
|
240
|
+
<div class="carousel-inner">
|
241
|
+
HEREDOC
|
242
|
+
count = 0
|
243
|
+
filenames.each do |fname|
|
244
|
+
active = count == 0 ? 'active' : ''
|
245
|
+
body << <<~HEREDOC
|
246
|
+
<div class="carousel-item #{active}">
|
247
|
+
<img class="d-block w-80" src="/content/topics/images/#{fname}">
|
248
|
+
</div>
|
249
|
+
HEREDOC
|
250
|
+
count += 1
|
179
251
|
end
|
180
|
-
body <<
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
<div class="carousel-inner" role="listbox" style="margin: 20px; ">)
|
193
|
-
counter = 0
|
194
|
-
filenames.each do |nam|
|
195
|
-
ci = counter == 0 ? %(<div class="item active">) : %(<div class="item">)
|
196
|
-
body << ci
|
197
|
-
body << %(<img src=")
|
198
|
-
body << nam
|
199
|
-
body << %("/>"></div>)
|
200
|
-
counter += 1
|
201
|
-
end
|
202
|
-
body << %(</div> <a class="left carousel-control" role="button" href="#myCarousel" data-slide="prev">
|
203
|
-
<span class="glyphicon glyphicon-chevron-left"></span>
|
204
|
-
<span class="sr-only">Previous</span>
|
205
|
-
</a>
|
206
|
-
<a class="right carousel-control" role="button" href="#myCarousel" data-slide="next">
|
207
|
-
<span class="glyphicon glyphicon-chevron-right"></span>
|
208
|
-
<span class="sr-only">Next</span>
|
209
|
-
</a>
|
210
|
-
</div>)
|
252
|
+
body << <<~HEREDOC
|
253
|
+
</div>
|
254
|
+
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
|
255
|
+
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
256
|
+
<span class="sr-only">Previous</span>
|
257
|
+
</a>
|
258
|
+
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
|
259
|
+
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
260
|
+
<span class="sr-only">Next</span>
|
261
|
+
</a>
|
262
|
+
</div>
|
263
|
+
HEREDOC
|
211
264
|
body
|
212
265
|
end
|
213
266
|
|
@@ -236,13 +289,13 @@ HTMLSTRING
|
|
236
289
|
end
|
237
290
|
|
238
291
|
def include_ruby(name)
|
239
|
-
filename = Dir.pwd +
|
292
|
+
filename = Dir.pwd + '/content/content/topics/scripts/' + name.to_s + '.rb'
|
240
293
|
filecontents = File.new(filename).read
|
241
294
|
ruby_string filecontents
|
242
295
|
end
|
243
296
|
|
244
297
|
def include_python(name)
|
245
|
-
filename = Dir.pwd +
|
298
|
+
filename = Dir.pwd + '/content/content/topics/robotcode/' + name.to_s + '.py'
|
246
299
|
filecontents = File.new(filename).read
|
247
300
|
ruby_string filecontents
|
248
301
|
end
|
@@ -251,11 +304,9 @@ HTMLSTRING
|
|
251
304
|
"\n~~~~~~"
|
252
305
|
end
|
253
306
|
|
254
|
-
def code_end(lang =
|
307
|
+
def code_end(lang = '')
|
255
308
|
str = "~~~~~~\n"
|
256
|
-
if [
|
257
|
-
str += "{: .language-#{lang}}"
|
258
|
-
end
|
309
|
+
str += "{: .language-#{lang}}" if %w[ruby css java html].include? lang
|
259
310
|
str
|
260
311
|
end
|
261
312
|
|
@@ -264,42 +315,64 @@ HTMLSTRING
|
|
264
315
|
end
|
265
316
|
|
266
317
|
def include_code(name)
|
267
|
-
filename = Dir.pwd +
|
318
|
+
filename = Dir.pwd + '/content/content/topics/scripts/' + name
|
268
319
|
filecontents = File.new(filename).read
|
269
320
|
code_string filecontents
|
270
321
|
end
|
271
322
|
|
272
|
-
def
|
273
|
-
"<
|
323
|
+
def source_begin(language)
|
324
|
+
"<pre class=\"#{language}\">"
|
325
|
+
end
|
326
|
+
|
327
|
+
def source_end
|
328
|
+
'</pre>'
|
329
|
+
end
|
330
|
+
|
331
|
+
def postit_begin(title)
|
332
|
+
'<div class="postit">' + '<h5>' + title + '</h5>'
|
274
333
|
end
|
275
334
|
|
276
335
|
def postit_end
|
277
|
-
|
336
|
+
'</div>'
|
278
337
|
end
|
279
338
|
|
280
339
|
def ul_begin
|
281
|
-
|
340
|
+
'<ul>'
|
282
341
|
end
|
283
342
|
|
284
343
|
def ul_end
|
285
|
-
|
344
|
+
'</ul>'
|
286
345
|
end
|
287
346
|
|
288
|
-
def ul
|
347
|
+
def ul(body)
|
289
348
|
"<ul>#{body}</ul>"
|
290
349
|
end
|
291
350
|
|
292
|
-
def
|
293
|
-
|
294
|
-
|
351
|
+
def slide
|
352
|
+
'<slide_break></slide_break>'
|
353
|
+
end
|
354
|
+
|
355
|
+
def list_items(*items)
|
356
|
+
items.reduce('') do |s, i|
|
357
|
+
if i.start_with?('<ul>')
|
295
358
|
s + i
|
296
359
|
else
|
297
|
-
s +
|
360
|
+
s + '<li>' + i + '</li>'
|
298
361
|
end
|
299
362
|
end
|
300
363
|
end
|
301
364
|
|
302
365
|
def lab_note(title)
|
303
|
-
"<
|
366
|
+
"<h3 style=\"font-family:'Permanent Marker'; font-szie:18px; color: red;\">#{title}</h3>"
|
367
|
+
end
|
368
|
+
|
369
|
+
def toasty(header, *items)
|
370
|
+
str = %(<div class="border border-info rounded w-75 mx-auto p-2 m-3">
|
371
|
+
<h5>#{header}</h5><ul>)
|
372
|
+
items.each do |itm|
|
373
|
+
str += '<li>' + itm + '</li>'
|
374
|
+
end
|
375
|
+
str += '</ul></div>'
|
376
|
+
str
|
304
377
|
end
|
305
378
|
end
|