Class: Spirit::Render::Problem

Inherits:
Template
  • Object
show all
Defined in:
lib/spirit/render/templates/problem.rb

Overview

Renders a single problem. This class doesn’t do anything useful; use the child classes (e.g. Multi) instead. Child classes should override #valid?.

Direct Known Subclasses

Multi, Short, Table

Constant Summary collapse

FORMAT =

Required key in YAML markup. Value indicates type of problem.

'format'
QUESTION =

Required key in YAML markup. Value contains question body.

'question'
ANSWER =

Required key in YAML markup. Value contains answers.

'answer'
ID =

Generated ID.

'id'
KEYS =

Required keys.

[FORMAT, QUESTION, ANSWER]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(yaml, digest) ⇒ Problem

Creates a new problem from the given YAML.

Parameters:

  • yaml (Hash)

    parsed yaml object

  • digest (String)

    SHA-256 hash of yaml text

  • id (Fixnum)

    integer ID of question

Raises:



80
81
82
83
84
# File 'lib/spirit/render/templates/problem.rb', line 80

def initialize(yaml, digest)
  @yaml, @digest, @nesting, @id = yaml, digest, [], 0
  raise RenderError.new('Invalid problem.') unless @yaml[QUESTION].is_a? String
  @yaml[QUESTION] = markdown.render @yaml[QUESTION]
end

Instance Attribute Details

#digestObject (readonly)

Returns the value of attribute digest.



74
75
76
# File 'lib/spirit/render/templates/problem.rb', line 74

def digest
  @digest
end

#idObject

Returns the value of attribute id.



73
74
75
# File 'lib/spirit/render/templates/problem.rb', line 73

def id
  @id
end

#nestingObject

Returns the value of attribute nesting.



73
74
75
# File 'lib/spirit/render/templates/problem.rb', line 73

def nesting
  @nesting
end

Class Method Details

.accessor(*args) ⇒ Object

Dynamically creates accessor methods for YAML values.

Examples:

accessor :id


50
51
52
# File 'lib/spirit/render/templates/problem.rb', line 50

def accessor(*args)
  args.each { |arg| define_method(arg) { @yaml[arg] } }
end

.get_instance(hash, digest) ⇒ Problem

Returns problem.

Returns:



55
56
57
58
59
60
61
62
# File 'lib/spirit/render/templates/problem.rb', line 55

def get_instance(hash, digest)
  raise RenderError, "Missing 'format' key in given YAML" unless instantiable? hash
  klass = Spirit::Render.const_get(hash[FORMAT].capitalize)
  raise NameError unless klass < Problem
  klass.new(hash, digest)
rescue NameError
  raise RenderError, 'Unrecognized format: %p' % hash[FORMAT]
end

.parse(text) ⇒ Problem

Parses the given text for questions and answers. If the given text does not contain valid YAML or does not contain the format key, raises an RenderError.

Parameters:

  • text (String)

    embedded yaml

Returns:



39
40
41
42
43
44
45
# File 'lib/spirit/render/templates/problem.rb', line 39

def parse(text)
  digest = OpenSSL::Digest::SHA256.digest text
  yaml   = YAML.load text
  get_instance(yaml, digest)
rescue ::Psych::SyntaxError => e
  raise RenderError, e.message
end

Instance Method Details

#answerString, ...

Retrieves the answer from the given YAML object in a serializable form.

Returns:

  • (String, Numeric, TrueClass, FalseClass)

    answer

See Also:

  • #serializable


96
97
98
# File 'lib/spirit/render/templates/problem.rb', line 96

def answer
  serialize @yaml[ANSWER]
end

#render(locals = {}) ⇒ Object

TODO:

TODO should probably show some error message in the preview, so that the author doesn’t have to read the logs.

Raises:



88
89
90
91
# File 'lib/spirit/render/templates/problem.rb', line 88

def render(locals={})
  raise RenderError.new('Invalid problem.') unless valid?
  super @yaml.merge(locals)
end