coursegen 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +2 -0
  7. data/bin/cg +4 -0
  8. data/coursegen.gemspec +29 -0
  9. data/lib/coursegen/cli.rb +49 -0
  10. data/lib/coursegen/course/helpers/content_helpers.rb +139 -0
  11. data/lib/coursegen/course/helpers/lecture_helpers.rb +9 -0
  12. data/lib/coursegen/course/helpers/logging_helpers.rb +14 -0
  13. data/lib/coursegen/course/helpers/navigation_helpers.rb +64 -0
  14. data/lib/coursegen/course/helpers/sidebar_helpers.rb +63 -0
  15. data/lib/coursegen/course/lib/citem.rb +88 -0
  16. data/lib/coursegen/course/lib/helpers_.rb +9 -0
  17. data/lib/coursegen/course/lib/lectures.rb +91 -0
  18. data/lib/coursegen/course/lib/schedule_def.rb +13 -0
  19. data/lib/coursegen/course/lib/scheduler.rb +77 -0
  20. data/lib/coursegen/course/lib/search_data_generator.rb +21 -0
  21. data/lib/coursegen/course/lib/section.rb +74 -0
  22. data/lib/coursegen/course/lib/section_def.rb +10 -0
  23. data/lib/coursegen/course/lib/toc.rb +160 -0
  24. data/lib/coursegen/templates.rb +54 -0
  25. data/lib/coursegen/version.rb +3 -0
  26. data/lib/coursegen.rb +23 -0
  27. data/templates/Rules +98 -0
  28. data/templates/cg_config.rb +12 -0
  29. data/templates/cg_config.rb_sample +46 -0
  30. data/templates/content/bootstrap/css/custom.css +187 -0
  31. data/templates/content/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  32. data/templates/content/bootstrap/js/custom.js +7 -0
  33. data/templates/content/content/index.md.erb +4 -0
  34. data/templates/layouts/body_footer.html +8 -0
  35. data/templates/layouts/body_header.html.erb +6 -0
  36. data/templates/layouts/course.html +59 -0
  37. data/templates/layouts/main_navbar.html.erb +21 -0
  38. data/templates/lib/default.rb +5 -0
  39. data/test1/Rules +40 -0
  40. data/test1/content/index.html +14 -0
  41. data/test1/content/stylesheet.css +101 -0
  42. data/test1/layouts/default.html +29 -0
  43. data/test1/lib/default.rb +2 -0
  44. data/test1/nanoc.yaml +62 -0
  45. metadata +159 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 63fa8b9bda73769816f40b252c9087e4cffb48d1
4
+ data.tar.gz: 2c6fcbeffc45abacf2424a8db896d250dade7ade
5
+ SHA512:
6
+ metadata.gz: 5e8bfe6a515ea7bb22404c7bb2a0650b98e180bcf9f0e3f0f67b72db5d05ddac1f59a59b3c0c2c1394d4a06fce80e453e7d85af1d4f18bbeca4c010da0cef162
7
+ data.tar.gz: d9d5066535c85ea6544aca09e66636e5edd8b5e4c8a6c3eeb0b625e9b130c3ac3635d7052d9ad1dd9947df1caa38dbae28dba5df1c3c5d45d1a3f4884b4c87e4
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in coursegen.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Pito Salas
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Coursegen
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'coursegen'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install coursegen
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/coursegen/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/cg ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'coursegen/cli'
3
+
4
+ CourseGen::CLI.start
data/coursegen.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'coursegen/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "coursegen"
8
+ 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"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ puts spec.executables
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake"
24
+
25
+ spec.add_dependency "nanoc"
26
+ spec.add_dependency "thor"
27
+ spec.add_dependency "nanoc-toolbox"
28
+
29
+ end
@@ -0,0 +1,49 @@
1
+ require 'thor'
2
+ require "coursegen/templates"
3
+
4
+ module CourseGen
5
+ class CLI < Thor
6
+ include Thor::Actions
7
+
8
+ desc "new COURSE", "Create a new course by calling nanoc. Argument is name of the COURSE"
9
+ def new(course)
10
+ run("nanoc create-site #{course}")
11
+ end
12
+
13
+ desc "prepare", "Update with the latest coursegen code and templates."
14
+ def prepare
15
+ check_valid_directory
16
+ tplt = CourseGen::Templates.new
17
+ tplt.generate_all
18
+ end
19
+
20
+ desc "compile", "build the course and put resultant site into output directory"
21
+ def compile
22
+ run("nanoc compile")
23
+ end
24
+
25
+ desc "serve", "start local web server to test the course web site"
26
+ def serve
27
+ run("nanoc view")
28
+ end
29
+
30
+ desc "reset", "reset all generated content to bring the course back to a base state."
31
+ def reset
32
+ run "rm -frd tmp"
33
+ run "rm -frd output"
34
+ end
35
+
36
+ desc "view", "view course site locally in browser"
37
+ def view
38
+ run "open http://0.0.0.0:3000"
39
+ end
40
+
41
+ no_commands do
42
+ def check_valid_directory
43
+ CourseGen::Templates.new.valid_cg_directory? ?
44
+ say("Valid cg directory") :
45
+ error("Invalid cg directory")
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,139 @@
1
+ module ContentHelpers
2
+ def generate_detailed_schedule section
3
+ # binding.pry
4
+ end
5
+
6
+ def include_topic item_symbol
7
+ incorporated_topic = lookup_nitem("topics", item_symbol.to_s)
8
+ Toc.instance.record_inclusion @item, incorporated_topic
9
+ items[incorporated_topic.identifier].compiled_content
10
+ end
11
+
12
+ def lookup_nitem the_sect, short_name
13
+ Toc.instance.lookup_citem(the_sect, short_name).nitem
14
+ end
15
+
16
+ def link_to_doc label, file_name
17
+ "<a href=\"/docs/#{file_name}\">#{label}</a>"
18
+ end
19
+
20
+ def toc_link_to item
21
+ link_to_unless_current item[:title], item
22
+ end
23
+
24
+ def bold_red string
25
+ "<span style=\"color: red; font-style: italic;\">\#{string}</span>"
26
+ end
27
+
28
+ def italic_red string
29
+ " *#{string}*{: style=\"color: red\"} "
30
+ end
31
+
32
+ def ir string; italic_red(string); end
33
+
34
+ def include_image_old string, extra_class: nil
35
+ css_class = "img-responsive"
36
+ css_class += " img-"+extra_class unless extra_class.nil?
37
+
38
+ "<img src=\"/content/images/#{string}\" class=\"%s\" />" % css_class
39
+ end
40
+
41
+ def include_image filename_string, width: 8
42
+ template_string = <<-HTMLSTRING
43
+ <div class="row">
44
+ <div class="col-md-offset-2 col-md-#{width}">
45
+ <img src="/content/images/#{filename_string}" class="img-responsive img-thumbnail" />
46
+ </div>
47
+ </div>
48
+ HTMLSTRING
49
+ end
50
+
51
+ def important string=":"
52
+ "**Important#{string}**{: style=\"color: red\"}"
53
+ end
54
+
55
+ def nb string=""
56
+ "*NB: #{string}*{: style=\"color: green\"}"
57
+ end
58
+
59
+ def tbd string=""
60
+ "*[TO BE DETERMINED#{string}]*{: style=\"color: red\"}"
61
+ end
62
+
63
+ def deliverable string
64
+ "*Deliverable:*{: style=\"color: red\"} *#{string}*"
65
+ end
66
+
67
+ def team_deliverable string
68
+ "*Team Deliverable:*{: style=\"color: red\"} *#{string}*"
69
+ end
70
+
71
+ def discussion string
72
+ "*Discussion:*{: style=\"color: blue\"} *#{string}*"
73
+ end
74
+
75
+ def homework_hdr
76
+ "#### Homework due for today"
77
+ end
78
+
79
+ def carousel(filenames)
80
+ body = %~<div id="myCarousel" class="carousel slide" style="width: 500px; margin: 0 auto;">
81
+ <div class="carousel-inner" style="margin: 20px; ">~
82
+ counter = 0
83
+ filenames.each do
84
+ |nam|
85
+ if counter == 0
86
+ body << %~<div class="item active">~
87
+ else
88
+ body << %~<div class="item">~
89
+ end
90
+ body << %~<img src="~
91
+ body << "/content/images/#{nam}"
92
+ body << %~" class="img-polaroid" alt=""></div>~
93
+ counter += 1
94
+ end
95
+ body << %~</div> <a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>
96
+ <a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>
97
+ </div>~
98
+ body
99
+ end
100
+
101
+ def ruby_begin
102
+ "\n~~~~~~"
103
+ end
104
+
105
+ def ruby_end
106
+ "~~~~~~\n {: .language-ruby}"
107
+ end
108
+
109
+ def ruby_string (str)
110
+ ruby_begin + "\n" + str + "\n" + ruby_end
111
+ end
112
+
113
+ def include_ruby name
114
+ filename = "content/content/scripts/#{name.to_s}.rb"
115
+ filecontents = File.new(filename).read
116
+ ruby_string filecontents
117
+ end
118
+
119
+ def code_begin
120
+ "\n~~~~~~"
121
+ end
122
+
123
+ def code_end
124
+ "~~~~~~\n"
125
+ end
126
+
127
+ def code_string (str)
128
+ code_begin + "\n" + str + code_end
129
+ end
130
+
131
+ def include_code name
132
+ filename = "content/content/scripts/#{name.to_s}"
133
+ filecontents = File.new(filename).read
134
+ code_string filecontents
135
+ end
136
+
137
+
138
+
139
+ end
@@ -0,0 +1,9 @@
1
+ module LectureHelpers
2
+ def lecture_number_str citem
3
+ citem.lecture_number.to_s
4
+ end
5
+
6
+ def lecture_date
7
+ "-ddd-"
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module LoggingHelpers
2
+ def log_item_info
3
+ puts
4
+ puts "*** ITEM Info: #{item.identifier}"
5
+ puts "Parent = #{item.parent}"
6
+ puts "Children = #{item.children}"
7
+ puts "Reps = #{item.reps}"
8
+ pp item.attributes
9
+ end
10
+
11
+ def compiling item
12
+ #puts "* compiling #{item[:title]}"
13
+ end
14
+ end
@@ -0,0 +1,64 @@
1
+ module NavigationHelpers
2
+
3
+ def link_to_lecture item_symbol
4
+ link_to_section :lectures, item_symbol
5
+ end
6
+
7
+ def link_to_topic item_symbol
8
+ link_to_section :topics, item_symbol
9
+ end
10
+
11
+ def link_to_background item_symbol
12
+ link_to_section :background, item_symbol
13
+ end
14
+
15
+ def link_to_cribsheet item_symbol
16
+ link_to_section :cribsheets, item_symbol
17
+ end
18
+
19
+ def link_to_intro item_symbol
20
+ link_to_section :intro, item_symbol
21
+ end
22
+
23
+ def link_to_incubator item_symbol
24
+ link_to_section :incubator, item_symbol
25
+ end
26
+
27
+ def link_to_lab item_symbol
28
+ link_to_section :lab, item_symbol
29
+ end
30
+
31
+ def link_to_pa item_symbol
32
+ link_to_section :pa, item_symbol
33
+ end
34
+
35
+
36
+ def link_to_section section_symbol, item_symbol
37
+ the_item = lookup_nitem(section_symbol.to_s, item_symbol.to_s)
38
+ link_to_unless_current(the_item[:title], the_item.identifier)
39
+ end
40
+
41
+ def link_to_next toc, item
42
+ nav_markup "", toc.find_next_forn(item).nitem.path, "glyphicon glyphicon-chevron-right", "next page"
43
+ end
44
+
45
+ def link_to_prev toc, item
46
+ nav_markup "", toc.find_previous_forn(item).nitem.path, "glyphicon glyphicon-chevron-left", "previous page"
47
+ end
48
+
49
+ def link_to_inclusion item
50
+ inclusion = Toc.instance.lookup_inclusion(item)
51
+ if inclusion.nil?
52
+ "(never included)"
53
+ else
54
+ " (#{inclusion.identifier})"
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def nav_markup text, path, icon, tooltip=""
61
+ "<a class=\"btn btn-mini\" href=\"#{path}\"><i class=\"#{icon}\" rel=\"tooltip\" title=\"#{tooltip}\"></i>#{text}</a>"
62
+ end
63
+
64
+ end
@@ -0,0 +1,63 @@
1
+ module SidebarHelpers
2
+ def section_helper title:nil, selector:nil
3
+ sect = Toc.instance.section(selector)
4
+ str = "<li>
5
+ <label class=\"tree-toggler level1\">
6
+ #{collapsed_indicator(sect[0].collapsed)}
7
+ #{title}
8
+ </label>"
9
+ if sect.has_subsections?
10
+ str += nested_section(sect)
11
+ else
12
+ str += flat_section(sect)
13
+ end
14
+ str += "</li>"
15
+ end
16
+
17
+ def nested_section sect
18
+ sect.subsections.reduce("") {|acc, subs| acc + subsection_body(subs)}
19
+ end
20
+
21
+ def subsection_body sect
22
+ "<ul class=\"tree\">
23
+ <li>
24
+ <label class=\"tree-toggler level2\">
25
+ #{collapsed_indicator(sect.content.collapsed)}
26
+ #{sect.content.title}
27
+ </label>
28
+ #{subsection(sect, sect.content.collapsed)}
29
+ </li>
30
+ </ul>"
31
+ end
32
+
33
+ def collapsed_indicator(coll)
34
+ icon_markup(coll ? :plus : :minus)
35
+ end
36
+
37
+ def subsection subsect, collapsed
38
+ disp_clause = collapsed ? "display: none" : "display: block"
39
+ str = "<ul class=\"tree\" style=\"#{disp_clause}\">"
40
+ str = subsect.children.reduce(str) { |acc, item| acc + subsection_item_link(item) }
41
+ str += "</ul>"
42
+ end
43
+
44
+ def subsection_item_link tree_node
45
+ "<li class=\"#{tree_node.content.css_class}\"><a href=\"#{tree_node.content.path}\">#{tree_node.content.title}</a></li>"
46
+ end
47
+
48
+ def flat_section sect
49
+ disp_clause = sect[0].collapsed ? "display: none" : "display: block"
50
+ str = "<ul class=\"tree\" style=\"#{disp_clause}\">"
51
+ str = sect.reduce(str) { |acc, item| acc + flat_section_item_link(item) }
52
+ str += "</ul>"
53
+ end
54
+
55
+ def flat_section_item_link citem
56
+ "<li class=\"#{citem.css_class}\"><a href=\"#{citem.path}\">#{citem.title}</a></li>"
57
+ end
58
+
59
+ def icon_markup icon_type
60
+ css_class = {star: "glyphicon-star", plus: "glyphicon-plus-sign", minus: "glyphicon-minus-sign"}.fetch(icon_type)
61
+ "<span class=\"glyphicon #{css_class} glyphicon-small \"></span>"
62
+ end
63
+ end
@@ -0,0 +1,88 @@
1
+ require 'active_support/inflector'
2
+
3
+ #
4
+ # Curriculu Item decorates Nanoc Item
5
+ #
6
+ class CItem
7
+
8
+ attr_reader :order, :section, :subsection, :subsection_citem, :title,
9
+ :type, :identifier, :short_name, :status, :nitem, :css_class, :collapsed
10
+ attr_accessor :lecture_number, :lecture_date
11
+
12
+ # Callable with nitem=nil to create a mock
13
+ def initialize nitem=nil, ident=nil, type=nil, order=nil
14
+ if nitem != nil
15
+ raise ArgumentError, "invalid CItem contruction" unless ident.nil?
16
+ @nitem = nitem
17
+ defaults_from_nitem @nitem
18
+ parse_identifier @nitem.identifier
19
+ else
20
+ raise ArgumentError, "invalid CItem contruction" unless nitem.nil?
21
+ @nitem = nil
22
+ @status = nil
23
+ @type = type
24
+ @identifier = ident
25
+ @order = order
26
+ @title = ident
27
+ @style = nil
28
+ @collapsed = nil
29
+ parse_identifier ident
30
+ end
31
+ end
32
+
33
+ def hidden?
34
+ if @nitem.nil?
35
+ false
36
+ else
37
+ @nitem[:status] == 'hidden' || %w(css min.css js png).include?(@nitem[:extension])
38
+ end
39
+ end
40
+
41
+ def path
42
+ @nitem.path
43
+ end
44
+
45
+ def is_lecture?
46
+ !@lecture_date.nil?
47
+ end
48
+
49
+ def lecture_date_s
50
+ @lecture_date.strftime('%a %b %-d') unless @lecture_date.nil?
51
+ end
52
+
53
+ def lecture_number_s
54
+ "#{@section.singularize} #{@lecture_number.to_s}"
55
+ end
56
+
57
+ private
58
+
59
+ def defaults_from_nitem(nitem)
60
+ @type = @nitem[:type] || 'page'
61
+ fail ArgumentError, 'Invalid page type' unless ["page", "subsection"].include? @type
62
+
63
+ @subsection = nil
64
+ @status = @nitem[:status]
65
+ @order = @nitem[:order].to_i unless @nitem[:order].nil?
66
+ @identifier = @nitem.identifier
67
+ @section = @nitem[:section]
68
+ @title = @nitem[:title]
69
+ @css_class = @nitem[:css_class]
70
+ @collapsed = @nitem[:collapsed].nil? ? true : @nitem[:collapsed]
71
+ end
72
+
73
+ def parse_identifier ident
74
+ parts = ident.split("/")
75
+ @section ||= parts[2]
76
+ parsed_title = parts[-1].match(/^((\d*)_)?([^\/]*)$/)
77
+ raise RuntimeError, "Invalid item title" if parsed_title.nil?
78
+
79
+ @order ||= parsed_title[2].to_i
80
+ @short_name = parsed_title[3]
81
+ @title ||= short_name
82
+ if @type == "subsection"
83
+ @subsection = "/#{parts[1..-1].join('/')}/"
84
+ elsif @type == "page"
85
+ @subsection = "/#{parts[1..-2].join('/')}/"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,9 @@
1
+ include LoggingHelpers
2
+ include ContentHelpers
3
+ include NavigationHelpers
4
+ include LectureHelpers
5
+ include SidebarHelpers
6
+ include Nanoc::Helpers::Rendering
7
+ include Nanoc::Helpers::LinkTo
8
+ include Nanoc::Toolbox::Helpers::Navigation
9
+ include Nanoc::Helpers::Tagging
@@ -0,0 +1,91 @@
1
+ require 'tree'
2
+
3
+ class Lectures < Section
4
+ def initialize sect, citems, schedule=nil
5
+ super sect, citems
6
+ @schedule = schedule || ::Scheduler.new
7
+ @citems = sort_items
8
+ build_tree
9
+ end
10
+
11
+ def has_subsections?
12
+ true
13
+ end
14
+
15
+ def has_lecture_numbers?
16
+ true
17
+ end
18
+
19
+ def build_tree
20
+ lecture_num = 1
21
+ @root = Tree::TreeNode.new("root", "root")
22
+ @citems.each do |i|
23
+ i.lecture_number = lecture_num
24
+ i.lecture_date = @schedule.event_date_by_index(lecture_num - 1) # Lecture numbers are base 1
25
+ if i.type == "subsection"
26
+ @root.add(Tree::TreeNode.new(i.subsection, i)) rescue binding.pry
27
+ elsif i.type == "page"
28
+ parent_tree_node = parent_node_of(i)
29
+ parent_tree_node.add(Tree::TreeNode.new(i.identifier, i)) rescue binding.pry
30
+ lecture_num += 1
31
+ else
32
+ raise ArgumentError, "invalid lecture page type of #{i.type}for #{i.title}"
33
+ end
34
+ end
35
+ end
36
+
37
+ def parent_node_of citem
38
+ parent_node = @root[citem.subsection]
39
+ # binding.pry if parent_node.nil?
40
+ raise RuntimeError, "Cant find section for item: #{citem.identifier}" if parent_node.nil?
41
+ parent_node
42
+ end
43
+
44
+ def treenode_of citem
45
+ @root.find do
46
+ |tree_node|
47
+ if citem.type == "subsection"
48
+ citem.subsection == tree_node.name
49
+ else
50
+ citem.identifier == tree_node.name
51
+ end
52
+ end
53
+ end
54
+
55
+ def subsections
56
+ @root.children
57
+ end
58
+
59
+ def next_for(citem)
60
+ next_node = treenode_of(citem).next_sibling rescue binding.pry
61
+ if !next_node.nil?
62
+ next_node.content
63
+ else
64
+ citem
65
+ end
66
+ end
67
+
68
+ def previous_for(citem)
69
+ prev_node = treenode_of(citem).previous_sibling
70
+ if !prev_node.nil?
71
+ prev_node.content
72
+ else
73
+ citem
74
+ end
75
+ end
76
+
77
+ # def citem_lecture_number citem
78
+ # citem.lecture_number
79
+ # end
80
+
81
+ protected
82
+
83
+ # def sort_items
84
+ # @citems.sort_by { |i| [ i.type == "subsection" ? "A" : "B", i.order ] }
85
+ # end
86
+
87
+ def sort_items
88
+ @citems.sort_by! { |i| [ lookup_citem_by_identifier(i.subsection).order, ((i.type == "page" ? 100 : 1 ) * i.order) ] }
89
+ end
90
+
91
+ end
@@ -0,0 +1,13 @@
1
+ # Define schedule scheme for a lecture series
2
+
3
+ class ScheduleDef
4
+ attr_reader :first_day, :weekdays, :number, :skips
5
+
6
+ def initialize first_day: nil, weekdays: nil, number: nil, skips: []
7
+ @first_day = first_day
8
+ @weekdays = weekdays
9
+ @number = number
10
+ @skips = skips
11
+ end
12
+
13
+ end