Skip to content

Instantly share code, notes, and snippets.

@camillebaldock
Last active August 29, 2015 14:04
Show Gist options
  • Save camillebaldock/d985aefba32c4f257107 to your computer and use it in GitHub Desktop.
Save camillebaldock/d985aefba32c4f257107 to your computer and use it in GitHub Desktop.
Smartdown to Smart-Answer-Friendly models
class SmartdownCoversheet
def initialize(node)
@node = node
end
def title
node.elements.find{|element| element.is_a? Smartdown::Model::Element::MarkdownHeading}
end
#TODO: this will ignore any headings in the body; if I include headings, then "Next node" appears in the text
def body
paragraphs = []
for element in node.elements
if element.is_a? Smartdown::Model::Element::MarkdownParagraph
paragraphs << GovspeakPresenter.new(element.content.to_s).html
end
#TODO: this should be any type of question
if element.is_a? Smartdown::Model::Element::MultipleChoice
return paragraphs.join
end
end
paragraphs.join
end
end
class SmartdownMultipleChoice < SmartdownQuestion
def options
question = node.elements.find{|element| element.is_a? Smartdown::Model::Element::MultipleChoice}
choice_hash = {}
question.choices.each do |choice|
choice_hash[choice[0]] = choice[1]
end
choice_hash
end
end
class SmartdownOutcome
attr_reader :node
def initialize(node)
@node = node
end
#TODO: title and body are common between SmartdownOutcome and SmartdownCoversheet..refactor!
def title
node.elements.find{|element| element.is_a? Smartdown::Model::Element::MarkdownHeading}
end
#TODO: this will ignore any headings in the body; if I include headings, then "Next node" appears in the text
def body
paragraphs = []
for element in node.elements
if element.is_a? Smartdown::Model::Element::MarkdownParagraph
paragraphs << GovspeakPresenter.new(element.content.to_s).html
end
#TODO: this should be any type of question
if element.is_a? Smartdown::Model::Element::MultipleChoice
return paragraphs.join
end
end
paragraphs.join
end
def next_steps
"not currently possible"
end
end
class SmartdownPreviousQuestion
attr_reader :node, :response
def initialize(node, response)
@node = node
@response = response
end
def label
node.elements.find{|element| element.is_a? Smartdown::Model::Element::MarkdownHeading}
end
end
class SmartdownQuestion
attr_reader :node
def initialize(node)
@node = node
end
def label
node.elements.find{|element| element.is_a? Smartdown::Model::Element::MarkdownHeading}
end
def hint
#first paragraph after question heading?
"todo"
end
def body
#any markdown paragraph before the question
paragraphs = []
for element in node.elements
if element.is_a? Smartdown::Model::Element::MarkdownParagraph
paragraphs << GovspeakPresenter.new(element.content.to_s).html
end
#TODO: this should be any type of question
if element.is_a? Smartdown::Model::Element::MultipleChoice
return paragraphs.join
end
end
paragraphs.join
end
def devolved_body
#any markdown paragraph after the question
element_index = 0
question_reached = false
until question_reached
element = node.elements[element_index]
if element.is_a? Smartdown::Model::Element::MultipleChoice
question_reached = true
end
element_index += 1
end
after_question_elements = elements[element_index..-1]
for element in after_question_elements
if element.is_a? Smartdown::Model::Element::MarkdownParagraph
paragraphs << GovspeakPresenter.new(element.content.to_s).html
end
end
paragraphs.join
end
def prefix
"not currently possible"
end
def suffix
"not currently possible"
end
def subtitle
"not currently possible"
end
end
class SmartdownState
attr_accessor :name, :responses, :smartdown_node, :flow
def initialize(name, responses)
@name = name
@responses = responses
get_smartdown_state
end
def need_id
"not currently defined"
end
def meta_description
"not currently defined"
end
def current_node
if smartdown_node.elements.any?{|element| element.is_a? Smartdown::Model::NextNodeRules}
if smartdown_node.elements.any?{|element| element.is_a? Smartdown::Model::Element::MultipleChoice}
SmartdownQuestion.new(smartdown_node)
else
SmartdownCoversheet.new(smartdown_node)
end
else
SmartdownOutcome.new(smartdown_node)
end
end
def previous_nodes
#TODO: this assumes the structure is always coversheet, questions, outcome (is that correct?)
if flow.nodes.count > 2
if smartdown_node.elements.any?{|element| element.is_a? Smartdown::Model::NextNodeRules}
previous_question_nodes = flow.nodes[1..-1] #just remove coversheet
else
previous_question_nodes = flow.nodes[1..-2] #remove coversheet and outcome
end
previous_question_nodes.each_with_index.map {|node, index|
#THIS WILL BREAK HORRIBLY WHEN WE HAVE MULTIPLE QUESTIONS
#we will need to count the number of questions in the node to know how many responses are involved
SmartdownPreviousQuestion.new(node, responses[index])
}
else
[]
end
end
private
def get_smartdown_state
coversheet_path = Rails.root.join('data', name, "#{name}.txt")
smartdown_responses = responses.clone
if !reponses.empty?
smartdown_responses << "y"
end
input = Smartdown::Parser::DirectoryInput.new(coversheet_path)
@flow = Smartdown::Parser::FlowInterpreter.new(input).interpret
engine = Smartdown::Engine.new(flow)
state = engine.process(smartdown_responses)
@smartdown_node = flow.node(state.get(:current_node))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment