-
Notifications
You must be signed in to change notification settings - Fork 0
/
bake_injected_exercise_question.rb
125 lines (115 loc) · 4.21 KB
/
bake_injected_exercise_question.rb
1
2
3
4
5
6
7
8
9
10
11
12
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
# frozen_string_literal: true
module Kitchen::Directions::BakeInjectedExerciseQuestion
def self.v1(question:, number:, options: {
only_number_solution: false,
add_dot: false,
problem_with_prefix: false,
suppress_summary: false
})
options.reverse_merge!(
only_number_solution: false,
add_dot: false,
problem_with_prefix: false,
suppress_summary: false
)
V1.new.bake(question: question, number: number, options: options)
end
class V1
def bake(question:, number:, options:)
id = question.id
in_appendix = question.has_ancestor?(:page) && question.ancestor(:page).has_class?('appendix')
in_preface = question.has_ancestor?(:page) && question.ancestor(:page).has_class?('preface')
alphabetical_multipart =
question.search("div[data-type='alphabetical-question-multipart']")&.first&.present?
# Store label in pantry
unless options[:only_number_solution]
label_number = if in_appendix || in_preface
"#{question.ancestor(:page).count_in(:book)}.#{number}"
else
"#{question.ancestor(:chapter).count_in(:book)}.#{number}"
end
question.target_label(label_text: 'exercise', custom_content: label_number)
end
# Synthesize multiple choice solution
if question.answers
case question.answers[:type]
when 'a'
alphabet = *('a'..'z')
else
raise('Unsupported list type for multiple choice options')
end
letter_answers = question.correct_answer_letters(alphabet)
end
if options[:suppress_summary]
question.solutions('$[data-solution-type="summary"]').each(&:trash)
end
if letter_answers.present?
text_content = "#{letter_answers.join(', ')}#{'.' if options[:add_dot]}"
answer_letters_span = "<span class=\"answer-letters\">#{text_content}</span>"
if !question.solution
question.append(child:
<<~HTML
<div data-type="question-solution">
#{answer_letters_span}
</div>
HTML
)
else
question.solution.prepend(child: answer_letters_span)
end
end
# Bake question
unless options[:only_number_solution]
if options[:problem_with_prefix]
problem_number = <<~HTML
<div class="os-prefix">
<span class="os-label">#{I18n.t('problem')}</span>
<span class="os-number">#{number}</span>
</div>
HTML
if question.solution
problem_number = <<~HTML
<a class="os-prefix" href='##{id}-solution'>
<span class="os-label">#{I18n.t('problem')}</span>
<span class="os-number">#{number}</span>
</a>
HTML
end
else
problem_number = <<~HTML
<span class='os-number'>#{number}</span>
<span class='os-divider'>. </span>
HTML
if question.solution
problem_number = <<~HTML
<a class='os-number' href='##{id}-solution'>#{number}</a><span class='os-divider'>. </span>
HTML
end
end
end
context = question.exercise_context_in_question&.cut&.paste
question.prepend(child:
<<~HTML
#{problem_number unless options[:only_number_solution]}
<div class="os-problem-container">
#{context if context.present?}#{"<span class='os-divider'>. </span>" if context.present?}
#{question.stimulus&.cut&.paste}
#{alphabetical_multipart ? question.search("div[data-type='alphabetical-question-multipart']").cut.paste : question.stem.cut.paste}
#{question.answers&.cut&.paste}
</div>
HTML
)
# Bake solution
Kitchen::Directions::BakeInjectedExerciseSolution.v1(
question: question,
id: id,
number: number,
options: {
problem_with_prefix: options[:problem_with_prefix],
suppress_summary: options[:suppress_summary]
}
)
question.search('div[data-type="answer-feedback"]').each(&:trash)
end
end
end