Module: CS50

Defined in:
lib/jekyll-theme-cs50.rb,
lib/jekyll-theme-cs50/constants.rb

Overview

Defined Under Namespace

Modules: Filters, MDhash, Mixins Classes: AfterBeforeBlock, AlertBlock, Block, CalendarTag, LocalTag, NextTag, SpoilerBlock, Tag, TestTag, VideoTag

Constant Summary collapse

PLUGINS =
{
  "jekyll-algolia" => "1.7.1",
  "jekyll-default-layout" => "0.1.5",
  "jekyll-optional-front-matter" => "0.3.2",
  "jekyll-redirect-from" => "0.16.0",
  "jekyll-titles-from-headings" => "0.5.3"
}.freeze
DEFAULTS =
{
  "cs50" => {
    "local" => {
      "day" => "numeric",
      "hour" => "numeric",
      "minute" => "numeric",
      "month" => "long",
      "timeZoneName" => "short",
      "weekday" => "long",
      "year" => "numeric"
    },
    "locale" => "en",
    "tz" => "America/New_York"
  },
  "exclude" => [
    "Gemfile",
    "Gemfile.lock",
    "vendor"
  ],
  "include" => [
    "license.md" # For OCW
  ],
  "optional_front_matter" => {
    "remove_originals" => true
  },
  "plugins"  => CS50::PLUGINS.keys
}.freeze
OVERRIDES =
{
  "kramdown" => {
    "gfm_quirks" => "paragraph_end",
    "hard_wrap" => false,
    "input" => "GFM",
    "math_engine" => "mathjax",
    "syntax_highlighter" => "rouge",
    "template" => ""
  },
  "markdown" => "kramdown",
  "permalink" => "pretty",
  "redirect_from" => {
    "json" => false
  },
  "sass" => {
    "style" => "compressed"
  },
  "theme" => "jekyll-theme-cs50"
}.freeze

Class Method Summary collapse

Class Method Details

.convert(s) ⇒ Object

Convert Markdown to HTML, preserving indentation (so that it can still be stripped elsewhere in pipeline)



27
28
29
30
31
# File 'lib/jekyll-theme-cs50.rb', line 27

def self.convert(s)
  markdown, indentation = CS50::unindent(s)
  html = $site.find_converter_instance(::Jekyll::Converters::Markdown).convert(markdown).strip
  CS50::indent(html, indentation)
end

.format(t) ⇒ Object

Format Time for time.cs50.io stackoverflow.com/a/19329068/5156190



35
36
37
# File 'lib/jekyll-theme-cs50.rb', line 35

def self.format(t)
  t.strftime("%Y%m%dT%H%M%S%z").sub(/\+0000/, "Z")
end

.indent(s, n) ⇒ Object

Indent multiline string



40
41
42
# File 'lib/jekyll-theme-cs50.rb', line 40

def self.indent(s, n)
  s.gsub(/^/, " " * n)
end

.sanitize(s) ⇒ Object

Sanitize string, allowing only these tags, which are a (reasonable) subset of developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content



46
47
48
# File 'lib/jekyll-theme-cs50.rb', line 46

def self.sanitize(s)
  Sanitize.fragment(s, :elements => ["b", "code", "em", "i", "img", "kbd", "span", "strong", "sub", "sup"]).strip
end

.strptime(s, now = nil) ⇒ Object

Parse time



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/jekyll-theme-cs50.rb', line 51

def self.strptime(s, now = nil)

  # Try YYYY-MM-DD HH:MM:SS
  begin
    Time.strptime(s, "%Y-%m-%d %H:%M:%S")
  rescue

    # Try YYYY-MM-DD HH:MM
    begin
      Time.strptime(s, "%Y-%m-%d %H:%M")
    rescue

      # Try HH:MM:SS, relative to now
      begin
        t = Time.strptime(s, "%H:%M:%S", now)
      rescue

        # Try HH:MM, relative to now
        begin
          t = Time.strptime(s, "%H:%M", now)
        rescue
          raise "Invalid datetime: #{s}"
        end
      end

      # Because Time.strptime parses relative to now's date,
      # not now's date plus time, add one day if t is in past
      if t < now
        t += 24 * 60 * 60
      end
      t
    end
  end
end

.unindent(s) ⇒ Object



88
89
90
91
92
# File 'lib/jekyll-theme-cs50.rb', line 88

def self.unindent(s)
  n = s.split("\n").select {|line| !line.strip.empty? }.map {|line| line.index(/[^\s]/) }.compact.min || 0
  s = s.gsub(/^[[:blank:]]{#{n}}/, "")
  return s, n
end