Class: Reloadlive::Render

Inherits:
Object
  • Object
show all
Includes:
Rack::Utils
Defined in:
lib/reloadlive/render.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, data) ⇒ Render

Returns a new instance of Render.



14
15
16
17
18
19
# File 'lib/reloadlive/render.rb', line 14

def initialize filename, data
  @filename = filename
  @data = data
  @codemap = {}
  @title = filename
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



12
13
14
# File 'lib/reloadlive/render.rb', line 12

def data
  @data
end

#filenameObject

Returns the value of attribute filename.



12
13
14
# File 'lib/reloadlive/render.rb', line 12

def filename
  @filename
end

#titleObject

Returns the value of attribute title.



12
13
14
# File 'lib/reloadlive/render.rb', line 12

def title
  @title
end

Instance Method Details

#check_cache(type, id) ⇒ Object



144
145
# File 'lib/reloadlive/render.rb', line 144

def check_cache(type, id)
end

#extract_code(data) ⇒ Object



49
50
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
85
86
87
88
89
# File 'lib/reloadlive/render.rb', line 49

def extract_code(data)
  data.gsub!(/^([ \t]*)(~~~+) ?([^\r\n]+)?\r?\n(.+?)\r?\n\1(~~~+)[ \t\r]*$/m) do
    m_indent = $1
    m_start  = $2 # ~~~
    m_lang   = $3
    m_code   = $4
    m_end    = $5 # ~~~

    # start and finish tilde fence must be the same length
    return '' if m_start.length != m_end.length

    lang   = m_lang ? m_lang.strip : nil
    id     = Digest::SHA1.hexdigest("#{lang}.#{m_code}")
    cached = check_cache(:code, id)

    # extract lang from { .ruby } or { #stuff .ruby .indent }
    # see http://johnmacfarlane.net/pandoc/README.html#delimited-code-blocks

    if lang
        lang = lang.match(/\.([^}\s]+)/)
        lang = lang[1] unless lang.nil?
    end

    @codemap[id] = cached   ?
      { :output => cached } :
      { :lang => lang, :code => m_code, :indent => m_indent }

    "#{m_indent}#{id}" # print the SHA1 ID with the proper indentation
  end

  data.gsub!(/^([ \t]*)``` ?([^\r\n]+)?\r?\n(.+?)\r?\n\1```[ \t]*\r?$/m) do
    lang   = $2 ? $2.strip : nil
    id     = Digest::SHA1.hexdigest("#{lang}.#{$3}")
    cached = check_cache(:code, id)
    @codemap[id] = cached   ?
      { :output => cached } :
      { :lang => lang, :code => $3, :indent => $1 }
    "#{$1}#{id}" # print the SHA1 ID with the proper indentation
  end
  data
end

#extract_yaml(data) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/reloadlive/render.rb', line 39

def extract_yaml(data)
  if data =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
    @title = YAML.load($1)['title']
    data = $'
  end
  data
rescue => e
  puts "YAML Exception reading #{@filename}: #{e.message}"
end

#formatted_data(encoding = nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/reloadlive/render.rb', line 21

def formatted_data encoding=nil
  data = @data.dup
  data = extract_yaml data
  data = extract_code data
  begin
    data = GitHub::Markup.render(@filename, data)
  rescue => e
    puts "Exception rendering #{@filename}: #{e.message}"
  end
  data = process_code(data, encoding)
  if data == @data
    p_lexer = Pygments::Lexer.find_by_extname(File.extname(@filename))
    lexer = p_lexer ? p_lexer.aliases.first : nil
    data = Pygments.highlight(data, :lexer => lexer, :options => {:encoding => encoding.to_s, :startinline => true})
  end
  data
end

#process_code(data, encoding = nil) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/reloadlive/render.rb', line 91

def process_code(data, encoding = nil)
  return data if data.nil? || data.size.zero? || @codemap.size.zero?

  blocks    = []
  @codemap.each do |id, spec|
    next if spec[:output] # cached

    code = spec[:code]

    remove_leading_space(code, /^#{spec[:indent]}/m)
    remove_leading_space(code, /^(  |\t)/m)

    blocks << [spec[:lang], code]
  end

  highlighted = []
  blocks.each do |lang, code|
    encoding ||= 'utf-8'
    begin
      # must set startinline to true for php to be highlighted without <?
      # http://pygments.org/docs/lexers/
      hl_code = Pygments.highlight(code, :lexer => lang, :options => {:encoding => encoding.to_s, :startinline => true})
    rescue
      hl_code = code
    end
    highlighted << hl_code
  end

  @codemap.each do |id, spec|
    body = spec[:output] || begin
      if (body = highlighted.shift.to_s).size > 0
        update_cache(:code, id, body)
        body
      else
        "<pre><code>#{CGI.escapeHTML(spec[:code])}</code></pre>"
      end
    end
    data.gsub!(id) do
      body
    end
  end

  data
end

#remove_leading_space(code, regex) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/reloadlive/render.rb', line 136

def remove_leading_space(code, regex)
  if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ regex }
    code.gsub!(regex) do
      ''
    end
  end
end

#update_cache(type, id, data) ⇒ Object



147
148
# File 'lib/reloadlive/render.rb', line 147

def update_cache(type, id, data)
end