coursegen 0.8.3 → 0.9.6
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 +78 -55
- 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 +104 -75
- 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 +62 -23
- 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 +36 -28
- data/.DS_Store +0 -0
- data/.vscode/settings.json +0 -2
- 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,69 +46,99 @@ 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
|
51
52
|
|
52
|
-
def
|
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
|
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 iconbadge3(icon, tooltip, shorttext="")
|
90
|
+
%(<svg class="iconbadge bi" 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>#{shorttext})
|
91
|
+
end
|
92
|
+
|
93
|
+
def iconbadge(icon, tooltip, shorttext="")
|
94
|
+
%(<svg class="iconbadge bi" 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><span class="icontext" >#{shorttext}</span>)
|
95
|
+
end
|
96
|
+
|
68
97
|
def textbadge(text, tooltip)
|
69
98
|
%(<span class="label label-info" data-toggle="tooltip" data-placement="top" title="#{tooltip}">#{text}</span>)
|
70
99
|
end
|
71
100
|
|
72
|
-
def
|
101
|
+
def iconbadge2(icon, tooltip)
|
73
102
|
%(<span class="fas fa-#{icon} themefg" data-toggle="tooltip" data-placement="top" title="#{tooltip}"></span>)
|
74
103
|
end
|
75
104
|
|
76
105
|
def pdfbadge
|
77
|
-
iconbadge(
|
106
|
+
iconbadge('file-earmark-richtext-fill', 'Submit a pdf file', "pdf")
|
78
107
|
end
|
79
108
|
|
80
109
|
def codebadge
|
81
|
-
iconbadge(
|
110
|
+
iconbadge('file-code-fill', 'Work on code in your portfolio', "portfolio")
|
82
111
|
end
|
83
112
|
|
84
113
|
def cloudbadge
|
85
|
-
iconbadge(
|
114
|
+
iconbadge('cloud-fill', 'Work on code in your portfolio', 'portfolio')
|
86
115
|
end
|
87
116
|
|
88
117
|
def zipbadge
|
89
|
-
iconbadge(
|
118
|
+
iconbadge('file-earmark-zip-fill', 'Submit work in a zipfile', 'zip')
|
90
119
|
end
|
91
120
|
|
92
121
|
def partbadge
|
93
|
-
iconbadge(
|
122
|
+
iconbadge('heart-half', 'Graded for participation only - pass/fail', 'participation')
|
94
123
|
end
|
95
124
|
|
96
125
|
def timebadge
|
97
|
-
iconbadge(
|
126
|
+
iconbadge('alarm-fill', 'Must be submitted first thing on day of class', 'early submit')
|
98
127
|
end
|
99
128
|
|
100
129
|
def teambadge
|
101
|
-
iconbadge(
|
130
|
+
iconbadge('people-fill', 'Team Deliverable', 'team deliverable')
|
102
131
|
end
|
103
132
|
|
104
133
|
def include_image_old(filename_string, extra_class: nil)
|
105
|
-
css_class =
|
106
|
-
css_class +=
|
134
|
+
css_class = 'img-responsive'
|
135
|
+
css_class += ' img-' + extra_class unless extra_class.nil?
|
107
136
|
<<-HTMLSTRING
|
108
137
|
<img src="#{filename_string}" class=\"%s\" />" % css_class
|
109
138
|
HTMLSTRING
|
110
139
|
end
|
111
140
|
|
112
|
-
def include_image(filename_string, extra:
|
141
|
+
def include_image(filename_string, extra: '')
|
113
142
|
<<~HTMLSTRING
|
114
143
|
<div class="row">
|
115
144
|
<div class="col-md-offset-2 col-md-8">
|
@@ -119,13 +148,13 @@ module ContentHelpers
|
|
119
148
|
HTMLSTRING
|
120
149
|
end
|
121
150
|
|
122
|
-
def image(filename_string, extra:
|
123
|
-
|
124
|
-
|
151
|
+
def image(filename_string, extra: '')
|
152
|
+
<<~HTMLSTRING
|
153
|
+
<img src="/content/topics/images/#{filename_string}" class="img-responsive img-thumbnail" #{extra}/>
|
125
154
|
HTMLSTRING
|
126
155
|
end
|
127
156
|
|
128
|
-
def important(string =
|
157
|
+
def important(string = ':')
|
129
158
|
<<-HTMLSTRING
|
130
159
|
<div class="cg-important">
|
131
160
|
#{string}
|
@@ -133,26 +162,26 @@ module ContentHelpers
|
|
133
162
|
HTMLSTRING
|
134
163
|
end
|
135
164
|
|
136
|
-
def nb(string =
|
165
|
+
def nb(string = ':')
|
137
166
|
<<-HTMLSTRING
|
138
167
|
<div class="label label-info">#{string}</div>
|
139
168
|
HTMLSTRING
|
140
169
|
end
|
141
170
|
|
142
|
-
def tbd(string =
|
171
|
+
def tbd(string = '')
|
143
172
|
"*[TO BE DETERMINED#{string}]*{: style=\"color: red\"}"
|
144
173
|
end
|
145
174
|
|
146
|
-
def deliverable(string, append =
|
175
|
+
def deliverable(string, append = '')
|
147
176
|
"*Deliverable:*{: style=\"color: red\"} #{string + append} "
|
148
177
|
end
|
149
178
|
|
150
179
|
def deliverable_po(string)
|
151
|
-
deliverable(string,
|
180
|
+
deliverable(string, ' *(graded for participation only)*')
|
152
181
|
end
|
153
182
|
|
154
183
|
def deliverable_popdf(string)
|
155
|
-
deliverable(string,
|
184
|
+
deliverable(string, ' *(pdf with name and hw number, graded for participation only)*')
|
156
185
|
end
|
157
186
|
|
158
187
|
def team_deliverable(string)
|
@@ -168,7 +197,7 @@ module ContentHelpers
|
|
168
197
|
end
|
169
198
|
|
170
199
|
def homework_hdr(show_legend: :on)
|
171
|
-
body =
|
200
|
+
body = '## Homework due for today'
|
172
201
|
legend = "\n**Legend**: #{partbadge}: Participation (pass/fail) | #{pdfbadge}: PDF | #{teambadge}: Team | #{zipbadge}: Attachment"
|
173
202
|
body += legend if show_legend == :on
|
174
203
|
body
|
@@ -185,8 +214,8 @@ module ContentHelpers
|
|
185
214
|
# body << %(" class="img-polaroid" alt=""></div>)
|
186
215
|
# counter += 1
|
187
216
|
# end
|
188
|
-
# body << %(</div> <a class="left carousel-control" href="#myCarousel" data-slide="prev"
|
189
|
-
# <a class="right carousel-control" href="#myCarousel" data-slide="next"
|
217
|
+
# body << %(</div> <a class="left carousel-control" href="#myCarousel" data-slide="prev"></a>
|
218
|
+
# <a class="right carousel-control" href="#myCarousel" data-slide="next"></a>
|
190
219
|
# </div>)
|
191
220
|
# body
|
192
221
|
# end
|
@@ -219,34 +248,33 @@ module ContentHelpers
|
|
219
248
|
# body
|
220
249
|
# end
|
221
250
|
|
222
|
-
def
|
251
|
+
def carousel_v4(filenames)
|
223
252
|
body = <<~HEREDOC
|
224
|
-
|
225
|
-
|
253
|
+
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
|
254
|
+
<div class="carousel-inner">
|
226
255
|
HEREDOC
|
227
256
|
count = 0
|
228
257
|
filenames.each do |fname|
|
229
|
-
active = count == 0 ?
|
258
|
+
active = count == 0 ? 'active' : ''
|
230
259
|
body << <<~HEREDOC
|
231
|
-
|
232
|
-
|
233
|
-
|
260
|
+
<div class="carousel-item #{active}">
|
261
|
+
<img class="d-block w-80" src="/content/topics/images/#{fname}">
|
262
|
+
</div>
|
234
263
|
HEREDOC
|
235
264
|
count += 1
|
236
265
|
end
|
237
266
|
body << <<~HEREDOC
|
267
|
+
</div>
|
268
|
+
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
|
269
|
+
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
270
|
+
<span class="sr-only">Previous</span>
|
271
|
+
</a>
|
272
|
+
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
|
273
|
+
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
274
|
+
<span class="sr-only">Next</span>
|
275
|
+
</a>
|
238
276
|
</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
277
|
HEREDOC
|
249
|
-
puts body
|
250
278
|
body
|
251
279
|
end
|
252
280
|
|
@@ -275,13 +303,13 @@ module ContentHelpers
|
|
275
303
|
end
|
276
304
|
|
277
305
|
def include_ruby(name)
|
278
|
-
filename = Dir.pwd +
|
306
|
+
filename = Dir.pwd + '/content/content/topics/scripts/' + name.to_s + '.rb'
|
279
307
|
filecontents = File.new(filename).read
|
280
308
|
ruby_string filecontents
|
281
309
|
end
|
282
310
|
|
283
311
|
def include_python(name)
|
284
|
-
filename = Dir.pwd +
|
312
|
+
filename = Dir.pwd + '/content/content/topics/robotcode/' + name.to_s + '.py'
|
285
313
|
filecontents = File.new(filename).read
|
286
314
|
ruby_string filecontents
|
287
315
|
end
|
@@ -290,11 +318,9 @@ module ContentHelpers
|
|
290
318
|
"\n~~~~~~"
|
291
319
|
end
|
292
320
|
|
293
|
-
def code_end(lang =
|
321
|
+
def code_end(lang = '')
|
294
322
|
str = "~~~~~~\n"
|
295
|
-
if [
|
296
|
-
str += "{: .language-#{lang}}"
|
297
|
-
end
|
323
|
+
str += "{: .language-#{lang}}" if %w[ruby css java html].include? lang
|
298
324
|
str
|
299
325
|
end
|
300
326
|
|
@@ -303,61 +329,64 @@ module ContentHelpers
|
|
303
329
|
end
|
304
330
|
|
305
331
|
def include_code(name)
|
306
|
-
filename = Dir.pwd +
|
332
|
+
filename = Dir.pwd + '/content/content/topics/scripts/' + name
|
307
333
|
filecontents = File.new(filename).read
|
308
334
|
code_string filecontents
|
309
335
|
end
|
310
336
|
|
311
337
|
def source_begin(language)
|
312
|
-
"<pre
|
338
|
+
"<pre class=\"#{language}\">"
|
313
339
|
end
|
314
340
|
|
315
341
|
def source_end
|
316
|
-
|
342
|
+
'</pre>'
|
317
343
|
end
|
318
344
|
|
319
|
-
|
320
|
-
|
321
|
-
"<div class=\"postit\">" + "<h5>" + title + "</h5>"
|
345
|
+
def postit_begin(title)
|
346
|
+
'<div class="postit">' + '<h5>' + title + '</h5>'
|
322
347
|
end
|
323
348
|
|
324
349
|
def postit_end
|
325
|
-
|
350
|
+
'</div>'
|
326
351
|
end
|
327
352
|
|
328
353
|
def ul_begin
|
329
|
-
|
354
|
+
'<ul>'
|
330
355
|
end
|
331
356
|
|
332
357
|
def ul_end
|
333
|
-
|
358
|
+
'</ul>'
|
334
359
|
end
|
335
360
|
|
336
|
-
def ul
|
361
|
+
def ul(body)
|
337
362
|
"<ul>#{body}</ul>"
|
338
363
|
end
|
339
364
|
|
340
|
-
def
|
341
|
-
|
342
|
-
|
365
|
+
def slide
|
366
|
+
'<slide_break></slide_break>'
|
367
|
+
end
|
368
|
+
|
369
|
+
def list_items(*items)
|
370
|
+
items.reduce('') do |s, i|
|
371
|
+
if i.start_with?('<ul>')
|
343
372
|
s + i
|
344
373
|
else
|
345
|
-
s +
|
374
|
+
s + '<li>' + i + '</li>'
|
346
375
|
end
|
347
376
|
end
|
348
377
|
end
|
349
378
|
|
350
379
|
def lab_note(title)
|
351
|
-
"<
|
380
|
+
"<h3 style=\"font-family:'Permanent Marker'; font-szie:18px; color: red;\">#{title}</h3>"
|
352
381
|
end
|
353
382
|
|
354
383
|
def toasty(header, *items)
|
355
|
-
str = %
|
384
|
+
str = %(<div class="border border-info rounded w-75 mx-auto p-2 m-3">
|
356
385
|
<h5>#{header}</h5><ul>)
|
357
386
|
items.each do |itm|
|
358
|
-
str +=
|
387
|
+
str += '<li>' + itm + '</li>'
|
359
388
|
end
|
360
|
-
str +=
|
389
|
+
str += '</ul></div>'
|
361
390
|
str
|
362
391
|
end
|
363
392
|
end
|