jekyll-theme-open-course 0.0.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -6
- data/_config.yml +33 -2
- data/_data/utility.yml +1 -1
- data/_layouts/calendar.html +54 -18
- data/_layouts/default.html +52 -36
- data/_layouts/policies.html +17 -0
- data/_layouts/projects.html +71 -0
- data/assets/css/print.css +26 -24
- data/assets/css/screen.scss +12 -0
- data/assets/js/site.js +38 -0
- data/exe/jtoc +76 -0
- data/lib/jtoc.rb +177 -0
- data/lib/starter_files/_config.yml.erb +82 -0
- data/lib/starter_files/_data/calendar.yml.erb +6 -0
- data/lib/starter_files/_data/utility.yml +35 -0
- data/lib/starter_files/index.md.erb +5 -0
- data/lib/starter_files/syllabus/_policies/academic-integrity.md +3 -0
- data/lib/starter_files/syllabus/_policies/assignment-submission.md +3 -0
- data/lib/starter_files/syllabus/_policies/books.md +13 -0
- data/lib/starter_files/syllabus/_policies/description.md +3 -0
- data/lib/starter_files/syllabus/_policies/goals.md +3 -0
- data/lib/starter_files/syllabus/_policies/grading-criteria.md +3 -0
- data/lib/starter_files/syllabus/_policies/grading-policy.md +3 -0
- data/lib/starter_files/syllabus/_policies/late-work.md +3 -0
- data/lib/starter_files/syllabus/_policies/materials.md +13 -0
- data/lib/starter_files/syllabus/_policies/objectives.md +3 -0
- data/lib/starter_files/syllabus/_policies/outcomes.md +3 -0
- data/lib/starter_files/syllabus/_policies/participation.md +3 -0
- data/lib/starter_files/syllabus/_policies/special-needs.md +3 -0
- data/lib/starter_files/syllabus/_policies/technology-policy.md +3 -0
- data/lib/starter_files/syllabus/_projects/project-00.md.erb +23 -0
- data/lib/starter_files/syllabus/_weeks/week-00.md.erb +11 -0
- data/projects/index.md +1 -30
- metadata +31 -25
- data/_data/weeks/01.yml +0 -21
- data/_data/weeks/02.yml +0 -1
- data/_data/weeks/03.yml +0 -1
- data/_data/weeks/04.yml +0 -1
- data/_data/weeks/05.yml +0 -1
- data/_data/weeks/06.yml +0 -1
- data/_data/weeks/07.yml +0 -1
- data/_data/weeks/08.yml +0 -1
- data/_data/weeks/09.yml +0 -1
- data/_data/weeks/10.yml +0 -1
- data/_data/weeks/11.yml +0 -1
- data/_data/weeks/12.yml +0 -1
- data/_data/weeks/13.yml +0 -1
- data/_data/weeks/14.yml +0 -1
- data/_data/weeks/15.yml +0 -1
- data/_data/weeks/16.yml +0 -1
- data/_projects/project-01.md +0 -25
- data/_projects/project-02.md +0 -25
- data/_projects/project-03.md +0 -25
- data/assets/.keep +0 -0
- data/assets/css/screen.css +0 -408
@@ -0,0 +1,12 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
/* http://meyerweb.com/eric/tools/css/reset/
|
4
|
+
v2.0 | 20110126
|
5
|
+
License: none (public domain)
|
6
|
+
*/
|
7
|
+
/* stylelint-disable */
|
8
|
+
/* Keep reset CSS to one minified line */
|
9
|
+
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}html,.reset{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}
|
10
|
+
/* stylelint-enable */
|
11
|
+
|
12
|
+
@import "typography";
|
data/assets/js/site.js
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
// Add a .js utility class to <html>
|
2
|
+
document.querySelector('html').classList.add('js');
|
3
|
+
|
4
|
+
// Capture and replicate the current week at the top of the calendar
|
5
|
+
if (document.querySelector('#calendar')) {
|
6
|
+
var this_week = document.querySelector('#this-week').closest('article'); // grab this week's <article>
|
7
|
+
var current_week = this_week.cloneNode(true); // make a copy of it,
|
8
|
+
this_week.querySelector('#this-week').id = ''; // remove the original #this-week id
|
9
|
+
current_week.classList.add('current'); // add a class of current to this week's article copy
|
10
|
+
current_week.classList.remove('past'); // remove the past class
|
11
|
+
current_week.querySelector('#this-week small').innerText = "This Week";
|
12
|
+
document.querySelector('#content').prepend(current_week); // insert the copy at the top of the calendar
|
13
|
+
if (location.hash === '') {
|
14
|
+
location.hash = '#this-week'; // point at the new hash position; viewport should show this one
|
15
|
+
}
|
16
|
+
var btn_show_calendar = document.createElement('a');
|
17
|
+
btn_show_calendar.id = "btn-show-calendar";
|
18
|
+
btn_show_calendar.href = "#null";
|
19
|
+
btn_show_calendar.text = "Show Previous Weeks"
|
20
|
+
btn_show_calendar.addEventListener('click', function(e) {
|
21
|
+
var past_weeks = document.querySelectorAll('article.past');
|
22
|
+
for (var week of past_weeks) {
|
23
|
+
week.classList.remove('past');
|
24
|
+
}
|
25
|
+
btn_show_calendar.remove();
|
26
|
+
e.preventDefault();
|
27
|
+
}
|
28
|
+
);
|
29
|
+
current_week.insertAdjacentElement('afterend', btn_show_calendar);
|
30
|
+
}
|
31
|
+
|
32
|
+
window.addEventListener('keyup', function(e) {
|
33
|
+
// console.log(e.keyCode);
|
34
|
+
// Toggle the visibility of gridlines when `g` is pressed
|
35
|
+
if (e.keyCode === 71) {
|
36
|
+
document.querySelector('html').classList.toggle('g');
|
37
|
+
}
|
38
|
+
})
|
data/exe/jtoc
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
4
|
+
|
5
|
+
require 'mercenary'
|
6
|
+
require 'jtoc'
|
7
|
+
|
8
|
+
Mercenary.program(:jtoc) do |p|
|
9
|
+
p.version JTOpenCourse::VERSION
|
10
|
+
p.description "A generator for the Open Course Jekyll theme"
|
11
|
+
p.syntax "jtoc <subcommand> [options]"
|
12
|
+
|
13
|
+
p.command(:version) do |c|
|
14
|
+
c.description "Ouput the version number"
|
15
|
+
c.syntax "version"
|
16
|
+
c.action do |_,_|
|
17
|
+
puts JTOpenCourse::VERSION
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
p.command(:setup) do |c|
|
22
|
+
c.syntax "setup"
|
23
|
+
c.description <<~DESC
|
24
|
+
Interactively set up a new course site.
|
25
|
+
DESC
|
26
|
+
c.action do |_,_|
|
27
|
+
puts "Enter the short identifier for this course:"
|
28
|
+
while true
|
29
|
+
path = gets.chomp
|
30
|
+
if JTOpenCourse::SiteBuilder.path_check(path)
|
31
|
+
puts "A course with that identifier already exists. Try another:"
|
32
|
+
else
|
33
|
+
break
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
p.command(:new) do |c|
|
40
|
+
c.syntax "new PATH [options]"
|
41
|
+
c.description <<~DESC
|
42
|
+
Create a new course site at PATH. By design, the PATH value is used for the
|
43
|
+
directory value as well as the GitHub repo name, and the base URL for the
|
44
|
+
course site (e.g., https://example.com/PATH/)
|
45
|
+
DESC
|
46
|
+
c.option 'monday', '-m DATE', '--monday DATE', 'Set the first Monday of the term (e.g., 2020-01-13)'
|
47
|
+
c.option 'weeks', '-w NUM', '--weeks NUM', 'Set the number of weeks in the term'
|
48
|
+
c.option 'projects', '-p NUM', '--projects NUM', 'Set the number of major projects in the course'
|
49
|
+
c.option 'days', '-d DAYS', '--days DAYS', 'Set the course meeting days (e.g., "Monday, Wednesday")'
|
50
|
+
c.option 'url', '-u URL', '--url URL', 'Set the course URL (e.g., https://example.com).'
|
51
|
+
c.option 'number', '-n COURSE', '--number COURSE', 'Set the course number (e.g., "COM 101")'
|
52
|
+
c.option 'title', '-l TITLE', '--title TITLE', 'Set the course title (e.g., "Intro to Communication")'
|
53
|
+
c.option 'instructor', '-i NAME', '--instructor NAME', 'Set the instructor name (e.g., "Marcus Cicero")'
|
54
|
+
c.option 'cc', '-c', '--creative-commons', 'Add a Creative Commons license'
|
55
|
+
c.action do |args, options|
|
56
|
+
course = JTOpenCourse::SiteBuilder.new(args, options)
|
57
|
+
if course.path.exist?
|
58
|
+
puts "A directory named '#{course.name}' already exists. Aborting."
|
59
|
+
abort
|
60
|
+
end
|
61
|
+
course.create!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
p.action do |args, _|
|
66
|
+
if args.empty?
|
67
|
+
puts p
|
68
|
+
else
|
69
|
+
subcommand = args.first
|
70
|
+
unless p.has_command? subcommand
|
71
|
+
puts "Sorry, I don't know how to '#{args.first}'."
|
72
|
+
puts "Try running `jtgen --help` for help."
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/jtoc.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
module JTOpenCourse
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
VERSION = "1.0.1"
|
7
|
+
|
8
|
+
SPELLED_NUMS = %w(
|
9
|
+
Zero One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Fifteen
|
10
|
+
Sixteen Seventeen Eighteen Nineteen Twenty Twenty-One Twenty-Two Twenty-Three Twenty-Four
|
11
|
+
Twenty-Five
|
12
|
+
)
|
13
|
+
|
14
|
+
# No small amount of this code has been either inspired or just about lifted from Jekyll's
|
15
|
+
# ThemeBuilder class at https://github.com/jekyll/jekyll/blob/master/lib/jekyll/theme_builder.rb
|
16
|
+
|
17
|
+
class SiteBuilder
|
18
|
+
SCAFFOLD_DIRECTORIES = %w(
|
19
|
+
_data policies projects syllabus/_policies syllabus/_projects syllabus/_weeks
|
20
|
+
).freeze
|
21
|
+
|
22
|
+
SCAFFOLD_PAGE_STUBS = %w(
|
23
|
+
index.md projects/index.md policies/index.md
|
24
|
+
).freeze
|
25
|
+
|
26
|
+
DEFAULT_VALUES = {
|
27
|
+
weeks: 16,
|
28
|
+
projects: 3,
|
29
|
+
days: "Monday, Wednesday",
|
30
|
+
url: "http://example.com/",
|
31
|
+
number: "COM 101",
|
32
|
+
title: "Introduction to Communication",
|
33
|
+
instructor: "Horatio Q. Birdbath",
|
34
|
+
email: "instructor@example.com",
|
35
|
+
cc: false
|
36
|
+
}
|
37
|
+
|
38
|
+
attr_reader :counter, :name, :path, :anchor_date, :week_count, :project_count, :days, :url, :number, :title, :instructor, :cc, :email
|
39
|
+
|
40
|
+
def initialize(args, options)
|
41
|
+
@counter = 0
|
42
|
+
@name = args.first.chomp
|
43
|
+
@path = Pathname.new(File.expand_path(name, Dir.pwd))
|
44
|
+
|
45
|
+
@anchor_date = set_value(find_next_monday(options['monday']),find_next_monday)
|
46
|
+
@week_count = set_value(options['weeks'], DEFAULT_VALUES[:weeks]).to_i
|
47
|
+
@project_count = set_value(options['projects'], DEFAULT_VALUES[:projects]).to_i
|
48
|
+
@days = set_value(options['days'], DEFAULT_VALUES[:days]).split(/\W+/)
|
49
|
+
|
50
|
+
@url = set_value(options['url'],DEFAULT_VALUES[:url]).chomp('/')
|
51
|
+
@number = set_value(options['number'],DEFAULT_VALUES[:number])
|
52
|
+
@title = set_value(options['title'],DEFAULT_VALUES[:title])
|
53
|
+
@instructor = set_value(options['instructor'], set_value(query_git_config('user.name'),DEFAULT_VALUES[:instructor]))
|
54
|
+
@cc = set_value(options['cc'], DEFAULT_VALUES[:cc])
|
55
|
+
|
56
|
+
@email = set_value(query_git_config('user.email'),DEFAULT_VALUES[:email])
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.path_check(name)
|
60
|
+
Pathname.new(File.expand_path(name, Dir.pwd)).exist?
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_value(custom,default)
|
64
|
+
if custom.to_s.empty?
|
65
|
+
custom = default
|
66
|
+
end
|
67
|
+
custom
|
68
|
+
end
|
69
|
+
|
70
|
+
def query_git_config(val)
|
71
|
+
begin
|
72
|
+
val = `git config --global #{val}`.chomp
|
73
|
+
val.empty? ? false : val
|
74
|
+
rescue
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def find_next_monday(date=Date.today.to_s)
|
80
|
+
date = Date.parse(date)
|
81
|
+
while date.cwday > 1
|
82
|
+
date += 1
|
83
|
+
end
|
84
|
+
date
|
85
|
+
end
|
86
|
+
|
87
|
+
def create!
|
88
|
+
create_directories
|
89
|
+
create_config_yml
|
90
|
+
create_utility_data
|
91
|
+
create_calendar_data
|
92
|
+
create_projects
|
93
|
+
create_weeks
|
94
|
+
create_policies
|
95
|
+
create_page_stubs
|
96
|
+
end
|
97
|
+
|
98
|
+
def starter_path
|
99
|
+
@starter_path ||= Pathname.new(File.expand_path("starter_files", __dir__))
|
100
|
+
end
|
101
|
+
|
102
|
+
def create_directories
|
103
|
+
mkdir_p(SCAFFOLD_DIRECTORIES)
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_projects
|
107
|
+
for @counter in 1..@project_count do
|
108
|
+
process_file("syllabus/_projects/project-#{@counter.to_s.rjust(2,"0")}.md", "syllabus/_projects/project-00.md")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def create_weeks
|
113
|
+
for @counter in 1..@week_count do
|
114
|
+
process_file("syllabus/_weeks/week-#{@counter.to_s.rjust(2,"0")}.md", "syllabus/_weeks/week-00.md")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_policies
|
119
|
+
Dir.chdir(starter_path) do
|
120
|
+
Dir.glob("syllabus/_policies/*.md").each do |f|
|
121
|
+
process_file(f)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def create_config_yml
|
127
|
+
process_file("_config.yml")
|
128
|
+
end
|
129
|
+
|
130
|
+
def create_calendar_data
|
131
|
+
process_file("_data/calendar.yml")
|
132
|
+
end
|
133
|
+
|
134
|
+
def create_utility_data
|
135
|
+
process_file("_data/utility.yml")
|
136
|
+
end
|
137
|
+
|
138
|
+
def create_page_stubs
|
139
|
+
SCAFFOLD_PAGE_STUBS.each_with_index do |stub,c|
|
140
|
+
@counter = c
|
141
|
+
process_file(stub,"index.md")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def mkdir_p(directories)
|
146
|
+
Array(directories).each do |d|
|
147
|
+
FileUtils.mkdir_p(path.join(d))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def render_erb(contents)
|
152
|
+
ERB.new(contents, trim_mode: "<>").result binding
|
153
|
+
end
|
154
|
+
|
155
|
+
def process_file(output,input=output)
|
156
|
+
write_file(output,process_template(input))
|
157
|
+
end
|
158
|
+
|
159
|
+
def process_template(filename)
|
160
|
+
render_erb(find_template_file(filename).read)
|
161
|
+
end
|
162
|
+
|
163
|
+
def find_template_file(filename)
|
164
|
+
[
|
165
|
+
starter_path.join("#{filename}.erb"),
|
166
|
+
starter_path.join(filename.to_s)
|
167
|
+
].find(&:exist?)
|
168
|
+
end
|
169
|
+
|
170
|
+
def write_file(filename, contents)
|
171
|
+
full_path = path.join(filename)
|
172
|
+
File.write(full_path, contents)
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
url: <%= url %>
|
2
|
+
baseurl: /<%= name %>/
|
3
|
+
|
4
|
+
timezone: America/Chicago
|
5
|
+
|
6
|
+
course:
|
7
|
+
number: <%= number %>
|
8
|
+
title: <%= title %>
|
9
|
+
uid: <%= name %>
|
10
|
+
tagline: >
|
11
|
+
Write a course tagline in `_config.yml`
|
12
|
+
term: <%= anchor_date.year %>
|
13
|
+
# Set `days: ""` (empty string) for weekly/asynchronous classes
|
14
|
+
days: <%= '""' unless days.length > 0 %>
|
15
|
+
<% days.each do |d| %>- <%= d %>
|
16
|
+
<% end %>
|
17
|
+
<% if cc %>
|
18
|
+
license:
|
19
|
+
name: Creative Commons
|
20
|
+
url: https://creativecommons.org/licenses/by/4.0/
|
21
|
+
<% end %>
|
22
|
+
instructor:
|
23
|
+
honorific: Dr.
|
24
|
+
name: <%= instructor %>
|
25
|
+
title: Professor
|
26
|
+
full_title: Enter a full professional title in `_config.yml`
|
27
|
+
url: https://example.com/instructor/
|
28
|
+
github: https://github.com/example/
|
29
|
+
email: <%= email %>
|
30
|
+
office_hours: >
|
31
|
+
Detail your office hours in `_config.yml`
|
32
|
+
navigation:
|
33
|
+
- label: Calendar
|
34
|
+
href: "#this-week"
|
35
|
+
id: cal
|
36
|
+
- label: Projects
|
37
|
+
href: "projects/#current"
|
38
|
+
id: pro
|
39
|
+
- label: Policies
|
40
|
+
href: "policies/"
|
41
|
+
id: pol
|
42
|
+
|
43
|
+
collections_dir: syllabus
|
44
|
+
|
45
|
+
collections:
|
46
|
+
weeks:
|
47
|
+
projects:
|
48
|
+
policies:
|
49
|
+
# Rearrange the files listed here to change their order on the policies page.
|
50
|
+
# To remove a section from the policies page, you *must* delete the file in the
|
51
|
+
# /syllabus/_policies/ directory
|
52
|
+
order:
|
53
|
+
- description.md
|
54
|
+
- goals.md
|
55
|
+
- outcomes.md
|
56
|
+
- objectives.md
|
57
|
+
- books.md
|
58
|
+
- materials.md
|
59
|
+
- special-needs.md
|
60
|
+
- participation.md
|
61
|
+
- assignment-submission.md
|
62
|
+
- late-work.md
|
63
|
+
- grading-policy.md
|
64
|
+
- grading-criteria.md
|
65
|
+
- technology-policy.md
|
66
|
+
- academic-integrity.md
|
67
|
+
|
68
|
+
defaults:
|
69
|
+
- scope:
|
70
|
+
path: ""
|
71
|
+
values:
|
72
|
+
layout: "default"
|
73
|
+
|
74
|
+
theme: jekyll-theme-open-course
|
75
|
+
|
76
|
+
exclude:
|
77
|
+
- backstop_data
|
78
|
+
- backstop.json
|
79
|
+
- exe
|
80
|
+
- lib
|
81
|
+
- Rakefile
|
82
|
+
- "*.gemspec"
|
@@ -0,0 +1,6 @@
|
|
1
|
+
- begins: <%= anchor_date %>T00:00
|
2
|
+
expires: &two <%= anchor_date + 7 %>T00:00
|
3
|
+
<% week_num = 2; while week_num <= week_count %>
|
4
|
+
- begins: *<%= SPELLED_NUMS[week_num].downcase %>
|
5
|
+
expires: &<%= SPELLED_NUMS[week_num + 1].downcase %> <%= anchor_date + (week_num * 7) %>T00:00<% week_num += 1 %>
|
6
|
+
<% end %>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
day_offsets:
|
2
|
+
monday: 0
|
3
|
+
tuesday: 86400
|
4
|
+
wednesday: 172800
|
5
|
+
thursday: 259200
|
6
|
+
friday: 345600
|
7
|
+
saturday: 432000
|
8
|
+
sunday: 518400
|
9
|
+
spelled_nums:
|
10
|
+
- Zero
|
11
|
+
- One
|
12
|
+
- Two
|
13
|
+
- Three
|
14
|
+
- Four
|
15
|
+
- Five
|
16
|
+
- Six
|
17
|
+
- Seven
|
18
|
+
- Eight
|
19
|
+
- Nine
|
20
|
+
- Ten
|
21
|
+
- Eleven
|
22
|
+
- Twelve
|
23
|
+
- Thirteen
|
24
|
+
- Fourteen
|
25
|
+
- Fifteen
|
26
|
+
- Sixteen
|
27
|
+
- Seventeen
|
28
|
+
- Eighteen
|
29
|
+
- Nineteen
|
30
|
+
- Twenty
|
31
|
+
- Twenty-One
|
32
|
+
- Twenty-Two
|
33
|
+
- Twenty-Three
|
34
|
+
- Twenty-Four
|
35
|
+
- Twenty-Five
|