Class: Stencil::Template

Inherits:
Object
  • Object
show all
Defined in:
lib/stencil/template.rb

Direct Known Subclasses

DynamicTemplate

Defined Under Namespace

Classes: DataContext, DocumentScanner, State

Constant Summary collapse

DefaultFileOpener =
proc do |path|
  File.open(path) do |file|
    file.read
  end
end
BeginDirective =
%r{\[;}m
EndDirective =
%r{;\]}m
UntilDirective =
%r{.*?(?=#{BeginDirective})}m
FinishDirective =
%r{.*?(?=#{EndDirective})}m

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template, file = "", line = 1, column = 1) ⇒ Template

Returns a new instance of Template.



166
167
168
169
# File 'lib/stencil/template.rb', line 166

def initialize(template, file="", line=1, column=1)
  @template = parse(template, file, line, column)
  @file_opener = DefaultFileOpener
end

Instance Attribute Details

#file_opener=(value) ⇒ Object (writeonly)

Sets the attribute file_opener

Parameters:

  • value

    the value to set the attribute file_opener to.



209
210
211
# File 'lib/stencil/template.rb', line 209

def file_opener=(value)
  @file_opener = value
end

Class Method Details

.file(path, &file_open) ⇒ Object



158
159
160
161
162
163
# File 'lib/stencil/template.rb', line 158

def file(path, &file_open)
  file_open ||= DefaultFileOpener
  template = self.new(file_open[path], path)
  template.file_opener = file_open
  return template
end

.string(data, file = nil, line = nil, &file_open) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/stencil/template.rb', line 146

def string(data, file=nil, line=nil, &file_open)
  m = %r{^([^:]+):(\d+)}.match caller[0]
  file ||= m[1] unless m.nil?
  line ||= m[2].to_i unless m.nil?

  file ||= ""
  line ||= 1
  template = self.new(data, file, line)
  template.file_opener = file_open unless file_open.nil?
  return template
end

Instance Method Details

#parse(template, file = "", line = 1, column = 1) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/stencil/template.rb', line 217

def parse(template, file="", line=1, column=1)
  scanner = DocumentScanner.new(template, file, line, column)
  result = [Block.new(scanner.location, "")]
  last_newline = 0

  while scanner.rest?
    literal = scanner.scan(UntilDirective)

    unless literal.nil? or literal.empty? 
      result.last.add(Literal.new(scanner.location, literal))
    end

    delim = scanner.scan(BeginDirective)

    if delim.nil?
      result.last.add(Literal.new(scanner.location, scanner.rest))
      break
    end

    directive = scanner.scan(FinishDirective)

    directive = Directive.create(scanner.location, directive)
    directive.parsed(result)

    scanner.scan(EndDirective)
  end

  raise "Unterminated directives: #{result[1..-1].inspect}" unless result.length == 1
  result.last
end

#render(data) ⇒ Object



248
249
250
251
252
# File 'lib/stencil/template.rb', line 248

def render(data)
  data_context = DataContext.new(data)
  raw_results = render_raw(data_context)
  return raw_results.compact.join("")
end

#render_raw(data) ⇒ Object



254
255
256
257
# File 'lib/stencil/template.rb', line 254

def render_raw(data)
  state = State.new(data, &@file_opener)
  render_with(state, @template)
end

#render_with(state, template) ⇒ Object



259
260
261
262
263
264
265
266
267
268
# File 'lib/stencil/template.rb', line 259

def render_with(state, template)
  begin
    result = template.checked_render(state)
    return result
  rescue RenderError
    raise
  rescue Object => ex
    raise RenderError, [ex.class, ex.message].join(" ")
  end
end