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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +4 -4
  5. data/codecov.yaml +4 -0
  6. data/lib/kitchen/directions/bake_all_chapter_solutions_types.rb +30 -0
  7. data/lib/kitchen/directions/bake_all_numbered_exercise_types.rb +26 -0
  8. data/lib/kitchen/directions/bake_annotation_classes/main.rb +2 -2
  9. data/lib/kitchen/directions/bake_annotation_classes/v1.rb +3 -3
  10. data/lib/kitchen/directions/bake_appendix.rb +1 -0
  11. data/lib/kitchen/directions/bake_autotitled_exercise/main.rb +8 -0
  12. data/lib/kitchen/directions/bake_autotitled_exercise/v2.rb +33 -0
  13. data/lib/kitchen/directions/bake_autotitled_exercise/v3.rb +35 -0
  14. data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +3 -1
  15. data/lib/kitchen/directions/bake_chapter_references/v1.rb +1 -1
  16. data/lib/kitchen/directions/bake_chapter_solutions/v1.rb +1 -1
  17. data/lib/kitchen/directions/bake_chapter_summary.rb +1 -1
  18. data/lib/kitchen/directions/bake_example.rb +1 -1
  19. data/lib/kitchen/directions/bake_figure.rb +1 -15
  20. data/lib/kitchen/directions/bake_footnotes/v1.rb +1 -1
  21. data/lib/kitchen/directions/bake_iframes/v1.rb +2 -0
  22. data/lib/kitchen/directions/bake_index/v1.rb +1 -1
  23. data/lib/kitchen/directions/bake_index/v1.xhtml.erb +5 -9
  24. data/lib/kitchen/directions/{bake_injected_exercise.rb → bake_injected_exercise/bake_injected_exercise.rb} +10 -1
  25. data/lib/kitchen/directions/bake_injected_exercise/bake_injected_exercise_question.rb +4 -0
  26. data/lib/kitchen/directions/bake_learning_objectives.rb +13 -0
  27. data/lib/kitchen/directions/bake_lo_link_labels.rb +19 -0
  28. data/lib/kitchen/directions/bake_non_introduction_pages.rb +3 -1
  29. data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +1 -26
  30. data/lib/kitchen/directions/bake_notes/bake_note_exercise.rb +54 -0
  31. data/lib/kitchen/directions/bake_notes/bake_note_injected_question.rb +15 -0
  32. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb +0 -31
  33. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb +2 -2
  34. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v2.rb +2 -2
  35. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +2 -2
  36. data/lib/kitchen/directions/bake_notes/bake_unclassified_notes.rb +5 -3
  37. data/lib/kitchen/directions/bake_numbered_exercise/main.rb +8 -3
  38. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +48 -7
  39. data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +3 -0
  40. data/lib/kitchen/directions/bake_numbered_table/v2.rb +2 -1
  41. data/lib/kitchen/directions/bake_references/main.rb +6 -9
  42. data/lib/kitchen/directions/bake_references/v1.rb +22 -8
  43. data/lib/kitchen/directions/bake_references/v2.rb +9 -10
  44. data/lib/kitchen/directions/bake_references/v3.rb +32 -0
  45. data/lib/kitchen/directions/bake_screenreader_spans.rb +22 -0
  46. data/lib/kitchen/directions/bake_unnumbered_exercise.rb +16 -0
  47. data/lib/kitchen/directions/bake_unnumbered_figure.rb +26 -0
  48. data/lib/kitchen/directions/book_answer_key_container/eob_answer_key_container.xhtml.erb +9 -0
  49. data/lib/kitchen/directions/book_answer_key_container/v1.rb +6 -2
  50. data/lib/kitchen/directions/{eoc_composite_page_container → composite_page_container}/main.rb +1 -1
  51. data/lib/kitchen/directions/composite_page_container/v1.rb +28 -0
  52. data/lib/kitchen/directions/default_strategy_for_answer_key_solutions.rb +35 -0
  53. data/lib/kitchen/directions/move_custom_section_to_eoc_container/v1.rb +1 -1
  54. data/lib/kitchen/directions/move_solutions_to_answer_key/answer_key_inner_container.rb +29 -0
  55. data/lib/kitchen/element_base.rb +8 -4
  56. data/lib/kitchen/element_enumerator_base.rb +36 -0
  57. data/lib/kitchen/figure_element.rb +12 -4
  58. data/lib/kitchen/injected_exercise_element.rb +41 -0
  59. data/lib/kitchen/injected_exercise_element_enumerator.rb +21 -0
  60. data/lib/kitchen/injected_question_element.rb +7 -0
  61. data/lib/kitchen/patches/i18n.rb +4 -0
  62. data/lib/kitchen/patches/nokogiri.rb +8 -0
  63. data/lib/kitchen/patches/renderable.rb +1 -1
  64. data/lib/kitchen/section_element.rb +27 -0
  65. data/lib/kitchen/section_element_enumerator.rb +20 -0
  66. data/lib/kitchen/selectors/base.rb +6 -0
  67. data/lib/kitchen/selectors/standard_1.rb +2 -0
  68. data/lib/kitchen/templates/composite_page_template.xhtml.erb +10 -0
  69. data/lib/kitchen/version.rb +1 -1
  70. data/lib/locales/en.yml +4 -0
  71. data/lib/locales/es.yml +9 -1
  72. data/lib/locales/pl.yml +3 -0
  73. metadata +24 -14
  74. data/lib/kitchen/directions/book_answer_key_container/eob_answer_key_outer_container.xhtml.erb +0 -9
  75. data/lib/kitchen/directions/eoc_composite_page_container/v1.rb +0 -19
  76. data/lib/kitchen/directions/move_solutions_to_answer_key/main.rb +0 -18
  77. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/calculus.rb +0 -41
  78. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb +0 -40
  79. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb +0 -27
  80. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/precalculus.rb +0 -63
  81. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/uphysics.rb +0 -21
  82. data/lib/kitchen/directions/move_solutions_to_answer_key/v1.rb +0 -47
  83. 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
- BakeNumberedNotes.bake_note_exercise(note: note, exercise: exercise)
11
+ BakeNoteExercise.v1(note: note, exercise: exercise)
12
12
  end
13
13
  note.injected_questions.each do |question|
14
- BakeNumberedNotes.bake_note_injected_question(note: note, question: question)
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
- BakeNumberedNotes.bake_note_exercise(note: note, exercise: exercise, divider: '. ')
20
+ BakeNoteExercise.v1(note: note, exercise: exercise, divider: '. ')
21
21
  end
22
22
  note.injected_questions.each do |question|
23
- BakeNumberedNotes.bake_note_injected_question(note: note, question: question)
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
- BakeNumberedNotes.bake_note_exercise(
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
- BakeNumberedNotes.bake_note_injected_question(note: note, question: question)
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
- def bake(exercise:, number:, suppress_solution_if: false,
6
- note_suppressed_solutions: false, cases: false)
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
- label_number = "#{exercise.ancestor(:chapter).count_in(:book)}.#{number}"
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 = "<a class='os-number' href='##{exercise.id}-solution'>#{number}</a>"
30
- bake_solution(exercise: exercise, number: number)
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
- <span class='os-divider'>. </span>
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']") && !table.top_captioned?
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
- book: book,
19
- metadata_source: metadata_source
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
- @content = chapter_area_references.paste
49
- book.body.append(child: render(file:
50
- '../../templates/eob_section_title_template.xhtml.erb'))
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
- @content = chapter_area_references.paste
31
- book.body.append(child: render(file:
32
- '../../templates/eob_section_title_template.xhtml.erb'))
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: true)
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
- book.body.append(child: render(file: 'eob_answer_key_outer_container.xhtml.erb'))
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kitchen
4
4
  module Directions
5
- module EocCompositePageContainer
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::EocCompositePageContainer.v1(
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
@@ -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
- # skips double indentations that the nokigiri sometimes picks up
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
  #