openstax_kitchen 12.2.0 → 16.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +4 -4
- data/codecov.yaml +4 -0
- data/lib/kitchen/directions/bake_all_chapter_solutions_types.rb +30 -0
- data/lib/kitchen/directions/bake_all_numbered_exercise_types.rb +26 -0
- data/lib/kitchen/directions/bake_annotation_classes/main.rb +2 -2
- data/lib/kitchen/directions/bake_annotation_classes/v1.rb +3 -3
- data/lib/kitchen/directions/bake_appendix.rb +1 -0
- data/lib/kitchen/directions/bake_autotitled_exercise/main.rb +8 -0
- data/lib/kitchen/directions/bake_autotitled_exercise/v2.rb +33 -0
- data/lib/kitchen/directions/bake_autotitled_exercise/v3.rb +35 -0
- data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +3 -1
- data/lib/kitchen/directions/bake_chapter_references/v1.rb +1 -1
- data/lib/kitchen/directions/bake_chapter_solutions/v1.rb +1 -1
- data/lib/kitchen/directions/bake_chapter_summary.rb +1 -1
- data/lib/kitchen/directions/bake_example.rb +1 -1
- data/lib/kitchen/directions/bake_figure.rb +1 -15
- data/lib/kitchen/directions/bake_footnotes/v1.rb +1 -1
- data/lib/kitchen/directions/bake_iframes/v1.rb +2 -0
- data/lib/kitchen/directions/bake_index/v1.rb +1 -1
- data/lib/kitchen/directions/bake_index/v1.xhtml.erb +5 -9
- data/lib/kitchen/directions/{bake_injected_exercise.rb → bake_injected_exercise/bake_injected_exercise.rb} +10 -1
- data/lib/kitchen/directions/bake_injected_exercise/bake_injected_exercise_question.rb +4 -0
- data/lib/kitchen/directions/bake_learning_objectives.rb +13 -0
- data/lib/kitchen/directions/bake_lo_link_labels.rb +19 -0
- data/lib/kitchen/directions/bake_non_introduction_pages.rb +3 -1
- data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +1 -26
- data/lib/kitchen/directions/bake_notes/bake_note_exercise.rb +54 -0
- data/lib/kitchen/directions/bake_notes/bake_note_injected_question.rb +15 -0
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb +0 -31
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb +2 -2
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v2.rb +2 -2
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +2 -2
- data/lib/kitchen/directions/bake_notes/bake_unclassified_notes.rb +5 -3
- data/lib/kitchen/directions/bake_numbered_exercise/main.rb +8 -3
- data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +48 -7
- data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +3 -0
- data/lib/kitchen/directions/bake_numbered_table/v2.rb +2 -1
- data/lib/kitchen/directions/bake_references/main.rb +6 -9
- data/lib/kitchen/directions/bake_references/v1.rb +22 -8
- data/lib/kitchen/directions/bake_references/v2.rb +9 -10
- data/lib/kitchen/directions/bake_references/v3.rb +32 -0
- data/lib/kitchen/directions/bake_screenreader_spans.rb +22 -0
- data/lib/kitchen/directions/bake_unnumbered_exercise.rb +16 -0
- data/lib/kitchen/directions/bake_unnumbered_figure.rb +26 -0
- data/lib/kitchen/directions/book_answer_key_container/eob_answer_key_container.xhtml.erb +9 -0
- data/lib/kitchen/directions/book_answer_key_container/v1.rb +6 -2
- data/lib/kitchen/directions/{eoc_composite_page_container → composite_page_container}/main.rb +1 -1
- data/lib/kitchen/directions/composite_page_container/v1.rb +28 -0
- data/lib/kitchen/directions/default_strategy_for_answer_key_solutions.rb +35 -0
- data/lib/kitchen/directions/move_custom_section_to_eoc_container/v1.rb +1 -1
- data/lib/kitchen/directions/move_solutions_to_answer_key/answer_key_inner_container.rb +29 -0
- data/lib/kitchen/element_base.rb +8 -4
- data/lib/kitchen/element_enumerator_base.rb +36 -0
- data/lib/kitchen/figure_element.rb +12 -4
- data/lib/kitchen/injected_exercise_element.rb +41 -0
- data/lib/kitchen/injected_exercise_element_enumerator.rb +21 -0
- data/lib/kitchen/injected_question_element.rb +7 -0
- data/lib/kitchen/patches/i18n.rb +4 -0
- data/lib/kitchen/patches/nokogiri.rb +8 -0
- data/lib/kitchen/patches/renderable.rb +1 -1
- data/lib/kitchen/section_element.rb +27 -0
- data/lib/kitchen/section_element_enumerator.rb +20 -0
- data/lib/kitchen/selectors/base.rb +6 -0
- data/lib/kitchen/selectors/standard_1.rb +2 -0
- data/lib/kitchen/templates/composite_page_template.xhtml.erb +10 -0
- data/lib/kitchen/version.rb +1 -1
- data/lib/locales/en.yml +4 -0
- data/lib/locales/es.yml +9 -1
- data/lib/locales/pl.yml +3 -0
- metadata +24 -14
- data/lib/kitchen/directions/book_answer_key_container/eob_answer_key_outer_container.xhtml.erb +0 -9
- data/lib/kitchen/directions/eoc_composite_page_container/v1.rb +0 -19
- data/lib/kitchen/directions/move_solutions_to_answer_key/main.rb +0 -18
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/calculus.rb +0 -41
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb +0 -40
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb +0 -27
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/precalculus.rb +0 -63
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/uphysics.rb +0 -21
- data/lib/kitchen/directions/move_solutions_to_answer_key/v1.rb +0 -47
- data/lib/kitchen/templates/eoc_section_template.xhtml.erb +0 -11
@@ -17,37 +17,6 @@ module Kitchen
|
|
17
17
|
def self.v3(book:, classes:, suppress_solution: true)
|
18
18
|
V3.new.bake(book: book, classes: classes, suppress_solution: suppress_solution)
|
19
19
|
end
|
20
|
-
|
21
|
-
# Used by V1, V2, V3
|
22
|
-
def self.bake_note_exercise(note:, exercise:, divider: ' ', suppress_solution: false)
|
23
|
-
exercise.add_class('unnumbered')
|
24
|
-
number = note.first('.os-number').text.gsub(/#/, '')
|
25
|
-
|
26
|
-
# bake problem
|
27
|
-
exercise.problem.wrap_children('div', class: 'os-problem-container')
|
28
|
-
exercise.search('[data-type="commentary"]').each(&:trash)
|
29
|
-
return unless exercise.solution
|
30
|
-
|
31
|
-
# bake solution in place
|
32
|
-
if suppress_solution
|
33
|
-
exercise.add_class('os-hasSolution')
|
34
|
-
exercise.solution.trash
|
35
|
-
else
|
36
|
-
BakeNumberedExercise.bake_solution_v1(
|
37
|
-
exercise: exercise,
|
38
|
-
number: number,
|
39
|
-
divider: divider
|
40
|
-
)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.bake_note_injected_question(note:, question:)
|
45
|
-
question.add_class('unnumbered')
|
46
|
-
number = note.first('.os-number').text.gsub(/#/, '')
|
47
|
-
Kitchen::Directions::BakeInjectedExerciseQuestion.v1(
|
48
|
-
question: question, number: number, only_number_solution: true
|
49
|
-
)
|
50
|
-
end
|
51
20
|
end
|
52
21
|
end
|
53
22
|
end
|
@@ -8,10 +8,10 @@ module Kitchen::Directions
|
|
8
8
|
book.chapters.pages.notes("$.#{klass}").each do |note|
|
9
9
|
bake_note(note: note, cases: cases)
|
10
10
|
note.exercises.each do |exercise|
|
11
|
-
|
11
|
+
BakeNoteExercise.v1(note: note, exercise: exercise)
|
12
12
|
end
|
13
13
|
note.injected_questions.each do |question|
|
14
|
-
|
14
|
+
BakeNoteInjectedQuestion.v1(note: note, question: question)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -17,10 +17,10 @@ module Kitchen::Directions
|
|
17
17
|
HTML
|
18
18
|
)
|
19
19
|
note.exercises.each do |exercise|
|
20
|
-
|
20
|
+
BakeNoteExercise.v1(note: note, exercise: exercise, divider: '. ')
|
21
21
|
end
|
22
22
|
note.injected_questions.each do |question|
|
23
|
-
|
23
|
+
BakeNoteInjectedQuestion.v1(note: note, question: question)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -25,12 +25,12 @@ module Kitchen::Directions
|
|
25
25
|
|
26
26
|
note.title&.trash
|
27
27
|
note.exercises.each do |exercise|
|
28
|
-
|
28
|
+
BakeNoteExercise.v1(
|
29
29
|
note: note, exercise: exercise, divider: '. ', suppress_solution: suppress_solution
|
30
30
|
)
|
31
31
|
end
|
32
32
|
note.injected_questions.each do |question|
|
33
|
-
|
33
|
+
BakeNoteInjectedQuestion.v1(note: note, question: question)
|
34
34
|
end
|
35
35
|
|
36
36
|
note.search("div[data-type='solution']").each&.trash if suppress_solution
|
@@ -3,15 +3,15 @@
|
|
3
3
|
module Kitchen
|
4
4
|
module Directions
|
5
5
|
module BakeUnclassifiedNotes
|
6
|
-
def self.v1(book:)
|
6
|
+
def self.v1(book:, bake_exercises: false)
|
7
7
|
book.notes.each do |note|
|
8
8
|
next unless note.classes.empty?
|
9
9
|
|
10
|
-
bake_note(note: note)
|
10
|
+
bake_note(note: note, bake_exercises: bake_exercises)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
def self.bake_note(note:)
|
14
|
+
def self.bake_note(note:, bake_exercises:)
|
15
15
|
note.wrap_children(class: 'os-note-body')
|
16
16
|
|
17
17
|
title = note.title&.cut
|
@@ -24,6 +24,8 @@ module Kitchen
|
|
24
24
|
</h3>
|
25
25
|
HTML
|
26
26
|
)
|
27
|
+
|
28
|
+
BakeNoteExercise.v2(note: note) if bake_exercises
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -3,14 +3,19 @@
|
|
3
3
|
module Kitchen
|
4
4
|
module Directions
|
5
5
|
module BakeNumberedExercise
|
6
|
+
# rubocop:disable Metrics/ParameterLists
|
7
|
+
# :/
|
6
8
|
def self.v1(exercise:, number:, suppress_solution_if: false,
|
7
|
-
note_suppressed_solutions: false, cases: false)
|
9
|
+
note_suppressed_solutions: false, cases: false, solution_stays_put: false)
|
8
10
|
V1.new.bake(exercise: exercise, number: number, suppress_solution_if: suppress_solution_if,
|
9
|
-
note_suppressed_solutions: note_suppressed_solutions, cases: cases
|
11
|
+
note_suppressed_solutions: note_suppressed_solutions, cases: cases,
|
12
|
+
solution_stays_put: solution_stays_put)
|
10
13
|
end
|
14
|
+
# rubocop:enable Metrics/ParameterLists
|
11
15
|
|
12
16
|
def self.bake_solution_v1(exercise:, number:, divider: '. ')
|
13
|
-
V1.new.bake_solution(exercise: exercise, number: number, divider: divider
|
17
|
+
V1.new.bake_solution(exercise: exercise, number: number, divider: divider,
|
18
|
+
solution_stays_put: false)
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
@@ -2,13 +2,25 @@
|
|
2
2
|
|
3
3
|
module Kitchen::Directions::BakeNumberedExercise
|
4
4
|
class V1
|
5
|
-
|
6
|
-
|
5
|
+
# rubocop:disable Metrics/ParameterLists
|
6
|
+
def bake(exercise:, number:, suppress_solution_if:,
|
7
|
+
note_suppressed_solutions:, cases:, solution_stays_put:)
|
7
8
|
problem = exercise.problem
|
8
9
|
solution = exercise.solution
|
9
10
|
|
11
|
+
in_appendix = exercise.has_ancestor?(:page) && exercise.ancestor(:page).has_class?('appendix')
|
12
|
+
|
10
13
|
# Store label information
|
11
|
-
|
14
|
+
if in_appendix
|
15
|
+
label_number = number
|
16
|
+
title_label = "<span class=\"os-title-label\">#{I18n.t('exercise')}</span>"
|
17
|
+
problem_divider = ''
|
18
|
+
else
|
19
|
+
label_number = "#{exercise.ancestor(:chapter).count_in(:book)}.#{number}"
|
20
|
+
title_label = ''
|
21
|
+
problem_divider = "<span class='os-divider'>. </span>"
|
22
|
+
end
|
23
|
+
|
12
24
|
exercise.target_label(label_text: 'exercise', custom_content: label_number, cases: cases)
|
13
25
|
|
14
26
|
problem_number = "<span class='os-number'>#{number}</span>"
|
@@ -26,25 +38,54 @@ module Kitchen::Directions::BakeNumberedExercise
|
|
26
38
|
solution.trash
|
27
39
|
exercise.add_class('os-hasSolution-trashed') if note_suppressed_solutions
|
28
40
|
else
|
29
|
-
problem_number =
|
30
|
-
|
41
|
+
problem_number = \
|
42
|
+
if solution_stays_put || in_appendix
|
43
|
+
"<span class='os-number'>#{number}</span>"
|
44
|
+
else
|
45
|
+
"<a class='os-number' href='##{exercise.id}-solution'>#{number}</a>"
|
46
|
+
end
|
47
|
+
bake_solution(
|
48
|
+
exercise: exercise,
|
49
|
+
number: number,
|
50
|
+
solution_stays_put: solution_stays_put,
|
51
|
+
in_appendix: in_appendix
|
52
|
+
)
|
31
53
|
end
|
32
54
|
end
|
33
55
|
|
34
56
|
problem.replace_children(with:
|
35
57
|
<<~HTML
|
58
|
+
#{title_label}
|
36
59
|
#{problem_number}
|
37
|
-
|
60
|
+
#{problem_divider}
|
38
61
|
<div class="os-problem-container">#{problem.children}</div>
|
39
62
|
HTML
|
40
63
|
)
|
41
64
|
end
|
65
|
+
# rubocop:enable Metrics/ParameterLists
|
42
66
|
|
43
|
-
def bake_solution(exercise:, number:, divider: '. ')
|
67
|
+
def bake_solution(exercise:, number:, solution_stays_put:, divider: '. ', in_appendix: false)
|
44
68
|
solution = exercise.solution
|
69
|
+
if solution_stays_put
|
70
|
+
solution.wrap_children(class: 'os-solution-container')
|
71
|
+
solution.prepend(child:
|
72
|
+
<<~HTML
|
73
|
+
<h4 class="solution-title" data-type="title">
|
74
|
+
<span class="os-text">#{I18n.t(:solution)}</span>
|
75
|
+
</h4>
|
76
|
+
HTML
|
77
|
+
)
|
78
|
+
return
|
79
|
+
end
|
80
|
+
|
45
81
|
solution.id = "#{exercise.id}-solution"
|
46
82
|
exercise.add_class('os-hasSolution')
|
47
83
|
|
84
|
+
if in_appendix
|
85
|
+
solution.wrap_children(class: 'os-solution-container')
|
86
|
+
return
|
87
|
+
end
|
88
|
+
|
48
89
|
solution.replace_children(with:
|
49
90
|
<<~HTML
|
50
91
|
<a class='os-number' href='##{exercise.id}'>#{number}</a>
|
@@ -65,6 +65,9 @@ module Kitchen
|
|
65
65
|
elsif table.text_heavy?
|
66
66
|
custom_table = CustomBody.new(table: table, klass: 'text-heavy')
|
67
67
|
custom_table.modify_body(has_fake_title: false)
|
68
|
+
elsif table.unstyled?
|
69
|
+
custom_table = CustomBody.new(table: table, klass: 'unstyled')
|
70
|
+
custom_table.modify_body(has_fake_title: false)
|
68
71
|
end
|
69
72
|
end
|
70
73
|
end
|
@@ -9,7 +9,8 @@ module Kitchen::Directions::BakeNumberedTable
|
|
9
9
|
Kitchen::Directions::BakeTableBody::V1.new.bake(table: table, number: number, cases: cases)
|
10
10
|
|
11
11
|
caption = ''
|
12
|
-
if table&.caption&.first("span[data-type='title']")
|
12
|
+
if (table&.caption&.first("span[data-type='title']") || table&.caption) \
|
13
|
+
&& !table.top_captioned?
|
13
14
|
caption_el = table.caption
|
14
15
|
caption_el.add_class('os-caption')
|
15
16
|
caption_el.name = 'span'
|
@@ -6,18 +6,15 @@ module Kitchen
|
|
6
6
|
#
|
7
7
|
module BakeReferences
|
8
8
|
def self.v1(book:, metadata_source:, numbered_title: false)
|
9
|
-
V1.new.bake(
|
10
|
-
book: book,
|
11
|
-
metadata_source: metadata_source,
|
12
|
-
numbered_title: numbered_title
|
13
|
-
)
|
9
|
+
V1.new.bake(book: book, metadata_source: metadata_source, numbered_title: numbered_title)
|
14
10
|
end
|
15
11
|
|
16
12
|
def self.v2(book:, metadata_source:)
|
17
|
-
V2.new.bake(
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
V2.new.bake(book: book, metadata_source: metadata_source)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.v3(book:, metadata_source:)
|
17
|
+
V3.new.bake(book: book, metadata_source: metadata_source)
|
21
18
|
end
|
22
19
|
end
|
23
20
|
end
|
@@ -5,11 +5,6 @@ module Kitchen::Directions::BakeReferences
|
|
5
5
|
renderable
|
6
6
|
|
7
7
|
def bake(book:, metadata_source:, numbered_title:)
|
8
|
-
@metadata = metadata_source.children_to_keep.copy
|
9
|
-
@klass = 'reference'
|
10
|
-
@uuid_prefix = '.'
|
11
|
-
@title = I18n.t(:references)
|
12
|
-
|
13
8
|
book.chapters.each do |chapter|
|
14
9
|
chapter.search('[data-type="cite"]').each do |link|
|
15
10
|
link.prepend(child:
|
@@ -17,6 +12,19 @@ module Kitchen::Directions::BakeReferences
|
|
17
12
|
<sup class="os-citation-number">#{link.count_in(:chapter)}</sup>
|
18
13
|
HTML
|
19
14
|
)
|
15
|
+
|
16
|
+
next if link.nil?
|
17
|
+
|
18
|
+
link_sibling = link.previous unless link.preceded_by_text?
|
19
|
+
next if link_sibling.nil?
|
20
|
+
|
21
|
+
next unless link_sibling&.raw&.attr('data-type') == 'cite'
|
22
|
+
|
23
|
+
link.prepend(sibling:
|
24
|
+
<<~HTML
|
25
|
+
<span class="os-reference-link-separator">, </span>
|
26
|
+
HTML
|
27
|
+
)
|
20
28
|
end
|
21
29
|
|
22
30
|
chapter.references.each do |reference|
|
@@ -44,10 +52,16 @@ module Kitchen::Directions::BakeReferences
|
|
44
52
|
HTML
|
45
53
|
)
|
46
54
|
end
|
55
|
+
|
47
56
|
chapter_area_references = book.chapters.search('.os-chapter-area').cut
|
48
|
-
|
49
|
-
|
50
|
-
'
|
57
|
+
|
58
|
+
Kitchen::Directions::CompositePageContainer.v1(
|
59
|
+
container_key: 'reference',
|
60
|
+
uuid_key: '.reference',
|
61
|
+
metadata_source: metadata_source,
|
62
|
+
content: chapter_area_references.paste,
|
63
|
+
append_to: book.body
|
64
|
+
)
|
51
65
|
end
|
52
66
|
end
|
53
67
|
end
|
@@ -2,14 +2,7 @@
|
|
2
2
|
|
3
3
|
module Kitchen::Directions::BakeReferences
|
4
4
|
class V2
|
5
|
-
renderable
|
6
|
-
|
7
5
|
def bake(book:, metadata_source:)
|
8
|
-
@metadata = metadata_source.children_to_keep.copy
|
9
|
-
@klass = 'references'
|
10
|
-
@uuid_prefix = '.'
|
11
|
-
@title = I18n.t(:references)
|
12
|
-
|
13
6
|
book.chapters.each do |chapter|
|
14
7
|
|
15
8
|
chapter.references.search('h3').trash
|
@@ -26,10 +19,16 @@ module Kitchen::Directions::BakeReferences
|
|
26
19
|
HTML
|
27
20
|
)
|
28
21
|
end
|
22
|
+
|
29
23
|
chapter_area_references = book.chapters.search('.os-chapter-area').cut
|
30
|
-
|
31
|
-
|
32
|
-
'
|
24
|
+
|
25
|
+
Kitchen::Directions::CompositePageContainer.v1(
|
26
|
+
container_key: 'references',
|
27
|
+
uuid_key: '.references',
|
28
|
+
metadata_source: metadata_source,
|
29
|
+
content: chapter_area_references.paste,
|
30
|
+
append_to: book.body
|
31
|
+
)
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::BakeReferences
|
4
|
+
class V3
|
5
|
+
def bake(book:, metadata_source:)
|
6
|
+
return unless book.references.any?
|
7
|
+
|
8
|
+
book.chapters.pages.each do |page|
|
9
|
+
page.references.each do |reference|
|
10
|
+
reference.titles.trash
|
11
|
+
reference.prepend(child:
|
12
|
+
Kitchen::Directions::EocSectionTitleLinkSnippet.v1(
|
13
|
+
page: page,
|
14
|
+
title_tag: 'h2',
|
15
|
+
wrapper: nil
|
16
|
+
)
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
chapter_area_references = book.chapters.references.cut
|
22
|
+
|
23
|
+
Kitchen::Directions::CompositePageContainer.v1(
|
24
|
+
container_key: 'references',
|
25
|
+
uuid_key: '.references',
|
26
|
+
metadata_source: metadata_source,
|
27
|
+
content: chapter_area_references.paste,
|
28
|
+
append_to: book.body
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen
|
4
|
+
module Directions
|
5
|
+
module BakeScreenreaderSpans
|
6
|
+
# Add text for accessibility.
|
7
|
+
# Additional screenreader spans can be added below.
|
8
|
+
def self.v1(book:)
|
9
|
+
book.search('u[data-effect="double-underline"]').each do |element|
|
10
|
+
element.add_previous_sibling(
|
11
|
+
'<span data-screenreader-only="true">double underline</span>'
|
12
|
+
)
|
13
|
+
end
|
14
|
+
book.search('u[data-effect="underline"]').each do |element|
|
15
|
+
element.add_previous_sibling(
|
16
|
+
'<span data-screenreader-only="true">underline</span>'
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen
|
4
|
+
module Directions
|
5
|
+
module BakeUnnumberedExercise
|
6
|
+
def self.v1(exercise:)
|
7
|
+
exercise.problem.wrap_children(class: 'os-problem-container')
|
8
|
+
return unless exercise.solution
|
9
|
+
|
10
|
+
exercise.solutions.each do |solution|
|
11
|
+
solution.wrap_children(class: 'os-solution-container')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen
|
4
|
+
module Directions
|
5
|
+
module BakeUnnumberedFigure
|
6
|
+
def self.v1(book:)
|
7
|
+
book.figures(only: :unnumbered?).each do |figure|
|
8
|
+
next unless figure.caption || figure.title
|
9
|
+
|
10
|
+
figure.wrap(%(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
|
11
|
+
title = figure.title&.cut
|
12
|
+
caption = figure.caption&.cut
|
13
|
+
figure.append(sibling:
|
14
|
+
<<~HTML
|
15
|
+
<div class="os-caption-container">
|
16
|
+
#{"<span class=\"os-title\" data-type=\"title\" id=\"#{title.id}\">#{title.children}</span>" if title}
|
17
|
+
#{'<span class="os-divider"> </span>' if title && caption}
|
18
|
+
#{"<span class=\"os-caption\">#{caption.children}</span>" if caption}
|
19
|
+
</div>
|
20
|
+
HTML
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<div class="os-eob os-<%= @solutions_or_solution %>-container" data-type="<%= @composite_element %>" data-uuid-key=".<%= @uuid_key %>">
|
2
|
+
<<%= @main_title_tag %> data-type="document-title">
|
3
|
+
<span class="os-text"><%= @title %></span>
|
4
|
+
</<%= @main_title_tag %>>
|
5
|
+
<div data-type="metadata" style="display: none;">
|
6
|
+
<h1 data-type="document-title" itemprop="name"><%= @title %></h1>
|
7
|
+
<%= @metadata.paste %>
|
8
|
+
</div>
|
9
|
+
</div>
|
@@ -4,10 +4,14 @@ module Kitchen::Directions::BookAnswerKeyContainer
|
|
4
4
|
class V1
|
5
5
|
renderable
|
6
6
|
|
7
|
-
def bake(book:, solutions_plural:
|
7
|
+
def bake(book:, solutions_plural:)
|
8
|
+
@composite_element = 'composite-chapter'
|
8
9
|
@metadata = book.metadata.children_to_keep.copy
|
9
10
|
@solutions_or_solution = solutions_plural ? 'solutions' : 'solution'
|
10
|
-
|
11
|
+
@title = I18n.t(:answer_key_title)
|
12
|
+
@main_title_tag = 'h1'
|
13
|
+
@uuid_key = @solutions_or_solution
|
14
|
+
book.body.append(child: render(file: 'eob_answer_key_container.xhtml.erb'))
|
11
15
|
book.body.first("div.os-eob.os-#{@solutions_or_solution}-container")
|
12
16
|
end
|
13
17
|
end
|
data/lib/kitchen/directions/{eoc_composite_page_container → composite_page_container}/main.rb
RENAMED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Kitchen
|
4
4
|
module Directions
|
5
|
-
module
|
5
|
+
module CompositePageContainer
|
6
6
|
# Creates a wrapper for the given content & appends it to the given element
|
7
7
|
#
|
8
8
|
# @param container_key [String] Appended to 'eoc.' to form the I18n key for the container title; also used as part of a class on the container.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::CompositePageContainer
|
4
|
+
class V1
|
5
|
+
renderable
|
6
|
+
|
7
|
+
def bake(container_key:, uuid_key:, metadata_source:, content:, append_to:)
|
8
|
+
@in_composite_chapter = append_to.is?(:composite_chapter)
|
9
|
+
@is_eoc = append_to.is?(:chapter) || @in_composite_chapter
|
10
|
+
@section = @is_eoc ? 'eoc' : 'eob'
|
11
|
+
@title = I18n.t(:"#{@section}.#{container_key}")
|
12
|
+
@uuid_key = uuid_key
|
13
|
+
@container_class_type = container_key
|
14
|
+
@metadata = metadata_source.children_to_keep.copy
|
15
|
+
@content = content
|
16
|
+
@main_title_tag = 'h1'
|
17
|
+
|
18
|
+
if @in_composite_chapter
|
19
|
+
@main_title_tag = 'h3'
|
20
|
+
elsif @is_eoc
|
21
|
+
@main_title_tag = 'h2'
|
22
|
+
end
|
23
|
+
|
24
|
+
append_to.append(child: render(file:
|
25
|
+
'../../templates/composite_page_template.xhtml.erb'))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::DefaultStrategyForAnswerKeySolutions
|
4
|
+
def self.v1(strategy_options:, chapter:, append_to:)
|
5
|
+
V1.new(
|
6
|
+
strategy_options
|
7
|
+
).bake(
|
8
|
+
chapter: chapter,
|
9
|
+
append_to: append_to
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
class V1
|
14
|
+
def bake(chapter:, append_to:)
|
15
|
+
bake_section(chapter: chapter, append_to: append_to)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def bake_section(chapter:, append_to:)
|
21
|
+
@selectors.each do |selector|
|
22
|
+
chapter.search("#{selector} div[data-type='solution']").each do |solution|
|
23
|
+
append_to.append(child: solution.cut.to_s) unless @condition.present? && !@condition
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# This method helps to obtain more strategy-specific params through
|
29
|
+
# "strategy_options: {blah1: 1, blah2: 2}"
|
30
|
+
def initialize(strategy_options)
|
31
|
+
@selectors = strategy_options[:selectors] || (raise 'missing selectors for strategy')
|
32
|
+
@condition = strategy_options[:condition]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -30,7 +30,7 @@ module Kitchen::Directions::MoveCustomSectionToEocContainer
|
|
30
30
|
section_clipboard.paste
|
31
31
|
end
|
32
32
|
|
33
|
-
Kitchen::Directions::
|
33
|
+
Kitchen::Directions::CompositePageContainer.v1(
|
34
34
|
container_key: container_key,
|
35
35
|
uuid_key: uuid_key,
|
36
36
|
metadata_source: metadata_source,
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::AnswerKeyInnerContainer
|
4
|
+
def self.v1(chapter:, metadata_source:, append_to:, solutions_plural: true)
|
5
|
+
V1.new.bake(
|
6
|
+
chapter: chapter,
|
7
|
+
metadata_source: metadata_source,
|
8
|
+
append_to: append_to,
|
9
|
+
solutions_plural: solutions_plural
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
class V1
|
14
|
+
renderable
|
15
|
+
|
16
|
+
def bake(chapter:, metadata_source:, append_to:, solutions_plural:)
|
17
|
+
@solutions_or_solution = solutions_plural ? 'solutions' : 'solution'
|
18
|
+
@uuid_key = "#{@solutions_or_solution}#{chapter.count_in(:book)}"
|
19
|
+
@metadata = metadata_source.children_to_keep.copy
|
20
|
+
@composite_element = 'composite-page'
|
21
|
+
@title = "#{I18n.t(:chapter)} #{chapter.count_in(:book)}"
|
22
|
+
@main_title_tag = 'h2'
|
23
|
+
|
24
|
+
append_to.append(
|
25
|
+
child: render(file: '../book_answer_key_container/eob_answer_key_container.xhtml.erb')
|
26
|
+
).first("div[data-uuid-key='.#{@uuid_key}']")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/kitchen/element_base.rb
CHANGED
@@ -82,9 +82,13 @@ module Kitchen
|
|
82
82
|
# Set the inner HTML for this element
|
83
83
|
# @see https://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node#inner_html=-instance_method Nokogiri::XML::Node#inner_html=
|
84
84
|
# @return Object
|
85
|
+
# @!method preceded_by_text
|
86
|
+
# Returns true if the immediately preceding sibling is text
|
87
|
+
# @return Boolean
|
85
88
|
def_delegators :@node, :name=, :name, :[], :[]=, :add_class, :remove_class,
|
86
89
|
:text, :wrap, :children, :to_html, :remove_attribute,
|
87
|
-
:key?, :classes, :path, :inner_html
|
90
|
+
:key?, :classes, :path, :inner_html=, :add_previous_sibling,
|
91
|
+
:preceded_by_text?
|
88
92
|
|
89
93
|
# @!method config
|
90
94
|
# Get the config for this element's document
|
@@ -502,8 +506,8 @@ module Kitchen
|
|
502
506
|
Element.new(node: raw.parent, document: document, short_type: "parent(#{short_type})")
|
503
507
|
end
|
504
508
|
|
505
|
-
# returns previous element
|
506
|
-
#
|
509
|
+
# returns previous element sibling
|
510
|
+
# (only returns elements or nil)
|
507
511
|
# nil if there's no previous sibling
|
508
512
|
#
|
509
513
|
def previous
|
@@ -754,7 +758,7 @@ module Kitchen
|
|
754
758
|
def_delegators :as_enumerator, :pages, :chapters, :terms, :figures, :notes, :tables, :examples,
|
755
759
|
:metadatas, :non_introduction_pages, :units, :titles, :exercises, :references,
|
756
760
|
:composite_pages, :composite_chapters, :solutions, :injected_questions,
|
757
|
-
:search_with
|
761
|
+
:search_with, :sections, :injected_exercises
|
758
762
|
|
759
763
|
# Returns this element as an enumerator (over only one element, itself)
|
760
764
|
#
|