Class: Showoff::Compiler::Variables

Inherits:
Object
  • Object
show all
Defined in:
lib/showoff/compiler/variables.rb

Overview

Adds variable interpolation to the compiler

Class Method Summary collapse

Class Method Details

.interpolate!(content) ⇒ String

Note:

Had side effects of altering state datastore.

Returns The content with variables interpolated.

Parameters:

  • content (String)

    A string of Markdown content which may contain Showoff variables.

Returns:

  • (String)

    The content with variables interpolated.

See Also:



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/showoff/compiler/variables.rb', line 13

def self.interpolate!(content)
  # update counters, incrementing section:minor if needed
  content.gsub!("~~~CURRENT_SLIDE~~~", Showoff::State.get(:slide_count).to_s)
  content.gsub!("~~~SECTION:MAJOR~~~", Showoff::State.get(:section_major).to_s)
  if content.include? "~~~SECTION:MINOR~~~"
    Showoff::State.increment(:section_minor)
    content.gsub!("~~~SECTION:MINOR~~~", Showoff::State.get(:section_minor).to_s)
  end

  # scan for pagebreak tags. Should really only be used for handout notes or supplemental materials
  content.gsub!("~~~PAGEBREAK~~~", '<div class="pagebreak">continued...</div>')

  # replace with form rendering placeholder
  content.gsub!(/~~~FORM:([^~]*)~~~/, '<div class="form wrapper" title="\1"></div>')

  # Now check for any kind of options
  content.scan(/(~~~CONFIG:(.*?)~~~)/).each do |match|
    parts = match[1].split('.') # Use dots ('.') to separate Hash keys
    value = Showoff::Config.get(*parts)

    unless value.is_a?(String)
      msg = "#{match[0]} refers to a non-String data type (#{value.class})"
      msg = "#{match[0]}: not found in settings data" if value.nil?
      Showoff::Logger.warn(msg)
      next
    end

    content.gsub!(match[0], value)
  end

  # Load and replace any file tags
  content.scan(/(~~~FILE:([^:~]*):?(.*)?~~~)/).each do |match|
    # make a list of code highlighting classes to include
    css  = match[2].split.collect {|i| "language-#{i.downcase}" }.join(' ')

    # get the file content and parse out html entities
    name = match[1]
    file = File.read(File.join(Showoff::Config.root, '_files', name)) rescue "Nonexistent file: #{name}"
    file = "Empty file: #{name}" if file.empty?
    file = HTMLEntities.new.encode(file) rescue "HTML encoding of #{name} failed"

    content.gsub!(match[0], "<pre class=\"highlight\"><code class=\"#{css}\">#{file}</code></pre>")
  end

  # insert font awesome icons
  content.gsub!(/\[(fa\w?)-(\S*) ?(.*)\]/, '<i class="\1 fa-\2 \3"></i>')

  # For fenced code blocks, translate the space separated classes into one
  # colon separated string so Commonmarker doesn't ignore the rest
  content.gsub!(/^`{3} *(.+)$/) {|s| "``` #{$1.split.join(':')}"}

  # escape any tags left and ensure they're in distinctly separate p tags so
  # that renderers that accept a string of tildes for fenced code blocks don't blow up.
  # @todo This is terrible and we need to design a better tag syntax.
  content.gsub!(/^~~~(.*?)~~~/, "\n\\~~~\\1~~~\n")

  content
end