openstax_kitchen 3.2.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/changelog.yml +27 -0
  3. data/.github/workflows/rubocop.yml +28 -0
  4. data/.gitignore +1 -1
  5. data/CHANGELOG.md +94 -1
  6. data/Gemfile.lock +26 -18
  7. data/README.md +16 -0
  8. data/codecov.yaml +1 -0
  9. data/docker/ci +0 -1
  10. data/docker/rubocop +22 -0
  11. data/lib/kitchen/book_document.rb +1 -1
  12. data/lib/kitchen/book_element.rb +16 -2
  13. data/lib/kitchen/chapter_element.rb +10 -13
  14. data/lib/kitchen/chapter_element_enumerator.rb +1 -1
  15. data/lib/kitchen/composite_chapter_element.rb +7 -11
  16. data/lib/kitchen/composite_chapter_element_enumerator.rb +21 -0
  17. data/lib/kitchen/composite_page_element.rb +15 -10
  18. data/lib/kitchen/composite_page_element_enumerator.rb +1 -1
  19. data/lib/kitchen/config.rb +14 -0
  20. data/lib/kitchen/directions/bake_appendix.rb +3 -1
  21. data/lib/kitchen/directions/bake_chapter_glossary/main.rb +18 -0
  22. data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +30 -0
  23. data/lib/kitchen/directions/bake_chapter_introductions.rb +23 -16
  24. data/lib/kitchen/directions/bake_chapter_introductions/chapter_introduction.xhtml.erb +0 -0
  25. data/lib/kitchen/directions/bake_chapter_key_concepts/main.rb +7 -2
  26. data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +12 -7
  27. data/lib/kitchen/directions/bake_chapter_key_equations.rb +26 -21
  28. data/lib/kitchen/directions/bake_chapter_references/main.rb +16 -0
  29. data/lib/kitchen/directions/bake_chapter_references/v1.rb +35 -0
  30. data/lib/kitchen/directions/bake_chapter_section_exercises/main.rb +2 -2
  31. data/lib/kitchen/directions/bake_chapter_section_exercises/v1.rb +2 -1
  32. data/lib/kitchen/directions/bake_chapter_solutions/main.rb +11 -0
  33. data/lib/kitchen/directions/bake_chapter_solutions/v1.rb +37 -0
  34. data/lib/kitchen/directions/bake_chapter_summary.rb +56 -43
  35. data/lib/kitchen/directions/bake_composite_chapters.rb +1 -1
  36. data/lib/kitchen/directions/bake_composite_pages.rb +1 -1
  37. data/lib/kitchen/directions/bake_equations.rb +2 -2
  38. data/lib/kitchen/directions/bake_example.rb +8 -1
  39. data/lib/kitchen/directions/bake_figure.rb +14 -1
  40. data/lib/kitchen/directions/bake_first_elements.rb +22 -0
  41. data/lib/kitchen/directions/bake_footnotes/main.rb +2 -2
  42. data/lib/kitchen/directions/bake_footnotes/v1.rb +13 -9
  43. data/lib/kitchen/directions/bake_free_response/free_response.xhtml.erb +10 -0
  44. data/lib/kitchen/directions/{bake_chapter_review → bake_free_response}/main.rb +3 -3
  45. data/lib/kitchen/directions/bake_free_response/v1.rb +29 -0
  46. data/lib/kitchen/directions/bake_further_research.rb +61 -0
  47. data/lib/kitchen/directions/bake_index/v1.rb +36 -26
  48. data/lib/kitchen/directions/bake_link_placeholders.rb +1 -1
  49. data/lib/kitchen/directions/bake_notes/bake_note_subtitle.rb +4 -0
  50. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb +43 -0
  51. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb +37 -0
  52. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v2.rb +25 -0
  53. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +32 -0
  54. data/lib/kitchen/directions/bake_numbered_exercise/main.rb +7 -2
  55. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +34 -12
  56. data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +29 -0
  57. data/lib/kitchen/directions/bake_numbered_table/main.rb +4 -0
  58. data/lib/kitchen/directions/bake_numbered_table/v1.rb +1 -24
  59. data/lib/kitchen/directions/bake_numbered_table/v2.rb +31 -0
  60. data/lib/kitchen/directions/bake_page_abstracts.rb +1 -1
  61. data/lib/kitchen/directions/bake_preface/main.rb +2 -2
  62. data/lib/kitchen/directions/bake_preface/v1.rb +3 -2
  63. data/lib/kitchen/directions/bake_references/main.rb +16 -0
  64. data/lib/kitchen/directions/bake_references/v1.rb +48 -0
  65. data/lib/kitchen/directions/bake_suggested_reading.rb +5 -0
  66. data/lib/kitchen/directions/bake_toc.rb +4 -2
  67. data/lib/kitchen/directions/book_answer_key_container/eob_answer_key_outer_container.xhtml.erb +9 -0
  68. data/lib/kitchen/directions/book_answer_key_container/main.rb +11 -0
  69. data/lib/kitchen/directions/book_answer_key_container/v1.rb +14 -0
  70. data/lib/kitchen/directions/chapter_review_container/chapter_review.xhtml.erb +9 -0
  71. data/lib/kitchen/directions/chapter_review_container/main.rb +11 -0
  72. data/lib/kitchen/directions/chapter_review_container/v1.rb +15 -0
  73. data/lib/kitchen/directions/eoc_section_title_link_snippet.rb +14 -1
  74. data/lib/kitchen/directions/move_exercises_to_eoc/main.rb +37 -0
  75. data/lib/kitchen/directions/{bake_chapter_review_exercises → move_exercises_to_eoc}/v1.rb +8 -10
  76. data/lib/kitchen/directions/{bake_chapter_review_exercises → move_exercises_to_eoc}/v2.rb +8 -9
  77. data/lib/kitchen/directions/move_exercises_to_eoc/v3.rb +49 -0
  78. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/main.rb +7 -3
  79. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/strategies/calculus.rb +1 -1
  80. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb +27 -0
  81. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/precalculus.rb +84 -0
  82. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/strategies/uphysics.rb +7 -5
  83. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/v1.rb +12 -6
  84. data/lib/kitchen/document.rb +20 -42
  85. data/lib/kitchen/element.rb +9 -3
  86. data/lib/kitchen/element_base.rb +108 -21
  87. data/lib/kitchen/element_enumerator_base.rb +33 -2
  88. data/lib/kitchen/element_enumerator_factory.rb +28 -12
  89. data/lib/kitchen/element_factory.rb +3 -3
  90. data/lib/kitchen/example_element.rb +8 -11
  91. data/lib/kitchen/example_element_enumerator.rb +1 -1
  92. data/lib/kitchen/exercise_element.rb +7 -10
  93. data/lib/kitchen/exercise_element_enumerator.rb +1 -1
  94. data/lib/kitchen/figure_element.rb +8 -11
  95. data/lib/kitchen/figure_element_enumerator.rb +1 -1
  96. data/lib/kitchen/id_tracker.rb +68 -0
  97. data/lib/kitchen/metadata_element.rb +8 -2
  98. data/lib/kitchen/metadata_element_enumerator.rb +1 -1
  99. data/lib/kitchen/note_element.rb +8 -11
  100. data/lib/kitchen/note_element_enumerator.rb +1 -1
  101. data/lib/kitchen/oven.rb +5 -1
  102. data/lib/kitchen/page_element.rb +27 -12
  103. data/lib/kitchen/page_element_enumerator.rb +1 -1
  104. data/lib/kitchen/patches/i18n.rb +34 -0
  105. data/lib/kitchen/patches/integer.rb +24 -0
  106. data/lib/kitchen/patches/nokogiri.rb +62 -0
  107. data/lib/kitchen/patches/nokogiri_profiling.rb +60 -0
  108. data/lib/kitchen/reference_element.rb +27 -0
  109. data/lib/kitchen/references_element_enumerator.rb +20 -0
  110. data/lib/kitchen/search_query.rb +31 -3
  111. data/lib/kitchen/selector.rb +25 -0
  112. data/lib/kitchen/selectors/base.rb +39 -0
  113. data/lib/kitchen/selectors/standard_1.rb +13 -0
  114. data/lib/kitchen/table_element.rb +8 -11
  115. data/lib/kitchen/table_element_enumerator.rb +1 -1
  116. data/lib/kitchen/templates/eob_section_title_template.xhtml.erb +10 -0
  117. data/lib/kitchen/templates/eoc_section_title_template.xhtml.erb +10 -0
  118. data/lib/kitchen/term_element.rb +5 -8
  119. data/lib/kitchen/term_element_enumerator.rb +1 -1
  120. data/lib/kitchen/unit_element.rb +13 -7
  121. data/lib/kitchen/unit_element_enumerator.rb +1 -1
  122. data/lib/kitchen/version.rb +1 -1
  123. data/lib/locales/en.yml +5 -1
  124. data/lib/locales/es.yml +33 -0
  125. data/lib/locales/pl.yml +3 -2
  126. data/lib/openstax_kitchen.rb +2 -5
  127. data/openstax_kitchen.gemspec +1 -0
  128. metadata +66 -25
  129. data/.github/config.yml +0 -14
  130. data/lib/kitchen/directions/bake_book_answer_key/eob_solutions_container.xhtml.erb +0 -9
  131. data/lib/kitchen/directions/bake_book_answer_key/main.rb +0 -11
  132. data/lib/kitchen/directions/bake_book_answer_key/v1.rb +0 -13
  133. data/lib/kitchen/directions/bake_chapter_glossary.rb +0 -39
  134. data/lib/kitchen/directions/bake_chapter_key_concepts/key_concepts.xhtml.erb +0 -16
  135. data/lib/kitchen/directions/bake_chapter_review/chapter_review.xhtml.erb +0 -9
  136. data/lib/kitchen/directions/bake_chapter_review/v1.rb +0 -13
  137. data/lib/kitchen/directions/bake_chapter_review_exercises/main.rb +0 -15
  138. data/lib/kitchen/directions/bake_chapter_review_exercises/review_exercises.xhtml.erb +0 -10
  139. data/lib/kitchen/directions/bake_exercises/main.rb +0 -12
  140. data/lib/kitchen/directions/bake_exercises/v1.rb +0 -169
  141. data/lib/kitchen/directions/bake_notes/bake_notes.rb +0 -48
  142. data/lib/kitchen/directions/bake_notes/bake_numbered_notes.rb +0 -63
  143. data/lib/kitchen/directions/bake_problem_first_elements.rb +0 -16
  144. data/lib/kitchen/transliterations.rb +0 -21
@@ -6,6 +6,7 @@ module Kitchen
6
6
  #
7
7
  module BakeSuggestedReading
8
8
  def self.v1(book:)
9
+ metadata_elements = book.metadata.children_to_keep.copy
9
10
  book.chapters.each do |chapter|
10
11
  suggested_reading = chapter.search('section.suggested-reading').cut
11
12
 
@@ -15,6 +16,10 @@ module Kitchen
15
16
  <h2 data-type="document-title">
16
17
  <span class="os-text">#{I18n.t(:eoc_suggested_reading)}</span>
17
18
  </h2>
19
+ <div data-type="metadata" style="display: none;">
20
+ <h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_suggested_reading)}</h1>
21
+ #{metadata_elements.paste}
22
+ </div>
18
23
  #{suggested_reading.paste}
19
24
  </div>
20
25
  HTML
@@ -31,9 +31,9 @@ module Kitchen
31
31
  <<~HTML
32
32
  <li cnx-archive-uri="" cnx-archive-shortid="" class="os-toc-unit">
33
33
  <a href="#">
34
- <span class="os-number"><span class="os-part-text">#{I18n.t(:unit)} </span> #{unit.count_in(:book)}</span>
34
+ <span class="os-number"><span class="os-part-text">#{I18n.t(:unit)} </span>#{unit.count_in(:book)}</span>
35
35
  <span class="os-divider"> </span>
36
- <span data-type itemprop class="os-text"> #{unit.title.children} </span>
36
+ <span data-type itemprop class="os-text">#{unit.title_text}</span>
37
37
  </a>
38
38
  <ol class="os-unit">
39
39
  #{chapters.map { |chapter| li_for_chapter(chapter) }.join("\n")}
@@ -96,6 +96,8 @@ module Kitchen
96
96
  when CompositePageElement
97
97
  if page.is_index?
98
98
  'os-toc-index'
99
+ elsif page.is_reference?
100
+ 'os-toc-reference'
99
101
  elsif page.has_ancestor?(:composite_chapter) || page.has_ancestor?(:chapter)
100
102
  'os-toc-chapter-composite-page'
101
103
  else
@@ -0,0 +1,9 @@
1
+ <div class="os-eob os-<%= @solutions_or_solution %>-container" data-type="composite-chapter" data-uuid-key=".<%= @solutions_or_solution %>">
2
+ <h1 data-type="document-title">
3
+ <span class="os-text"><%= I18n.t(:answer_key_title) %></span>
4
+ </h1>
5
+ <div data-type="metadata" style="display: none;">
6
+ <h1 data-type="document-title" itemprop="name"><%= I18n.t(:answer_key_title) %></h1>
7
+ <%= @metadata.paste %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BookAnswerKeyContainer
6
+ def self.v1(book:, solutions_plural: true)
7
+ V1.new.bake(book: book, solutions_plural: solutions_plural)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BookAnswerKeyContainer
4
+ class V1
5
+ renderable
6
+
7
+ def bake(book:, solutions_plural: true)
8
+ @metadata = book.metadata.children_to_keep.copy
9
+ @solutions_or_solution = solutions_plural ? 'solutions' : 'solution'
10
+ book.body.append(child: render(file: 'eob_answer_key_outer_container.xhtml.erb'))
11
+ book.body.first("div.os-eob.os-#{@solutions_or_solution}-container")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ <div class="os-eoc os-<%= @klass %>-container" data-type="composite-chapter" data-uuid-key=".<%= @klass %>">
2
+ <h2 data-type="document-title">
3
+ <span class="os-text"><%= @title %></span>
4
+ </h2>
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>
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module ChapterReviewContainer
6
+ def self.v1(chapter:, metadata_source:, klass: 'chapter-review')
7
+ V1.new.bake(chapter: chapter, metadata_source: metadata_source, klass: klass)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::ChapterReviewContainer
4
+ class V1
5
+ renderable
6
+
7
+ def bake(chapter:, metadata_source:, klass: 'chapter-review')
8
+ @metadata = metadata_source.children_to_keep.copy
9
+ @klass = klass
10
+ @title = I18n.t(:"eoc.#{klass}")
11
+ chapter.append(child: render(file: 'chapter_review.xhtml.erb'))
12
+ chapter.element_children[-1]
13
+ end
14
+ end
15
+ end
@@ -10,11 +10,24 @@ module Kitchen
10
10
  <h3 data-type="document-title" id="#{page.title.copied_id}">
11
11
  <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
12
12
  <span class="os-divider"> </span>
13
- <span class="os-text" data-type="" itemprop="">#{page.title.text}</span>
13
+ <span class="os-text" data-type="" itemprop="">#{page.title_text}</span>
14
14
  </h3>
15
15
  </a>
16
16
  HTML
17
17
  end
18
+
19
+ def self.v2(page:)
20
+ chapter = page.ancestor(:chapter)
21
+ <<~HTML
22
+ <div>
23
+ <h3 data-type="document-title" id="#{page.title.copied_id}">
24
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
25
+ <span class="os-divider"> </span>
26
+ <span class="os-text" data-type="" itemprop="">#{page.title_text}</span>
27
+ </h3>
28
+ </div>
29
+ HTML
30
+ end
18
31
  end
19
32
  end
20
33
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module MoveExercisesToEOC
6
+ def self.v1(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
7
+ V1.new.bake(
8
+ chapter: chapter,
9
+ metadata_source: metadata_source,
10
+ append_to: append_to,
11
+ klass: klass,
12
+ uuid_prefix: uuid_prefix
13
+ )
14
+ end
15
+
16
+ def self.v2(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
17
+ V2.new.bake(
18
+ chapter: chapter,
19
+ metadata_source: metadata_source,
20
+ append_to: append_to,
21
+ klass: klass,
22
+ uuid_prefix: uuid_prefix
23
+ )
24
+ end
25
+
26
+ def self.v3(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
27
+ V3.new.bake(
28
+ chapter: chapter,
29
+ metadata_source: metadata_source,
30
+ append_to: append_to,
31
+ klass: klass,
32
+ uuid_prefix: uuid_prefix
33
+ )
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Kitchen::Directions::BakeChapterReviewExercises
3
+ module Kitchen::Directions::MoveExercisesToEOC
4
4
  class V1
5
5
  renderable
6
6
 
7
- def bake(chapter:, metadata_source:, append_to:, klass:)
7
+ def bake(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
8
8
  @klass = klass
9
9
  @metadata = metadata_source.children_to_keep.copy
10
10
  @title = I18n.t(:"eoc.#{klass}")
11
+ @uuid_prefix = uuid_prefix
11
12
 
12
13
  exercise_clipboard = Kitchen::Clipboard.new
13
14
 
@@ -17,13 +18,6 @@ module Kitchen::Directions::BakeChapterReviewExercises
17
18
  sections.each do |exercise_section|
18
19
  exercise_section.first("[data-type='title']")&.trash
19
20
 
20
- exercise_section.exercises.each do |exercise|
21
- exercise.document.pantry(name: :link_text).store(
22
- "#{I18n.t(:exercise_label)} #{chapter.count_in(:book)}.#{exercise.count_in(:chapter)}",
23
- label: exercise.id
24
- )
25
- end
26
-
27
21
  exercise_section.cut(to: exercise_clipboard)
28
22
  end
29
23
  end
@@ -32,7 +26,11 @@ module Kitchen::Directions::BakeChapterReviewExercises
32
26
 
33
27
  @content = exercise_clipboard.paste
34
28
 
35
- append_to.append(child: render(file: 'review_exercises.xhtml.erb'))
29
+ append_to_element = append_to || chapter
30
+ @in_composite_chapter = append_to_element.is?(:composite_chapter)
31
+
32
+ append_to_element.append(child: render(file:
33
+ '../../templates/eoc_section_title_template.xhtml.erb'))
36
34
  end
37
35
  end
38
36
  end
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Kitchen::Directions::BakeChapterReviewExercises
3
+ module Kitchen::Directions::MoveExercisesToEOC
4
4
  # Main difference from v1 is the presence of a section title
5
5
  # and some additional wrappers
6
6
  class V2
7
7
  renderable
8
8
 
9
- def bake(chapter:, metadata_source:, append_to:, klass:)
9
+ def bake(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
10
10
  @klass = klass
11
11
  @metadata = metadata_source.children_to_keep.copy
12
12
  @title = I18n.t(:"eoc.#{klass}")
13
+ @uuid_prefix = uuid_prefix
13
14
 
14
15
  exercise_clipboard = Kitchen::Clipboard.new
15
16
 
@@ -21,12 +22,6 @@ module Kitchen::Directions::BakeChapterReviewExercises
21
22
 
22
23
  # Get parent page title
23
24
  section_title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
24
- exercise_section.exercises.each do |exercise|
25
- exercise.document.pantry(name: :link_text).store(
26
- "#{I18n.t(:exercise_label)} #{chapter.count_in(:book)}.#{exercise.count_in(:chapter)}",
27
- label: exercise.id
28
- )
29
- end
30
25
 
31
26
  # Configure section title & wrappers
32
27
  exercise_section.prepend(child: section_title)
@@ -44,7 +39,11 @@ module Kitchen::Directions::BakeChapterReviewExercises
44
39
  </div>
45
40
  HTML
46
41
 
47
- append_to.append(child: render(file: 'review_exercises.xhtml.erb'))
42
+ append_to_element = append_to || chapter
43
+ @in_composite_chapter = append_to_element[:'data-type'] == 'composite-chapter'
44
+
45
+ append_to_element.append(child: render(file:
46
+ '../../templates/eoc_section_title_template.xhtml.erb'))
48
47
  end
49
48
  end
50
49
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::MoveExercisesToEOC
4
+ # The difference from v1 is the presence of a section title
5
+ # and from v2 the lack of additional "os-section-area" and os-#{@klass} wrappers
6
+ class V3
7
+ renderable
8
+
9
+ def bake(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
10
+ @klass = klass
11
+ @metadata = metadata_source.children_to_keep.copy
12
+ @title = I18n.t(:"eoc.#{klass}")
13
+ @uuid_prefix = uuid_prefix
14
+
15
+ exercise_clipboard = Kitchen::Clipboard.new
16
+
17
+ chapter.non_introduction_pages.each do |page|
18
+ sections = page.search("section.#{@klass}")
19
+
20
+ sections.each do |exercise_section|
21
+ exercise_section.first("[data-type='title']")&.trash
22
+
23
+ section_title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
24
+
25
+ exercise_section.exercises.each do |exercise|
26
+ exercise.document.pantry(name: :link_text).store(
27
+ "#{I18n.t(:exercise_label)} #{chapter.count_in(:book)}.#{exercise.count_in(:chapter)}",
28
+ label: exercise.id
29
+ )
30
+ end
31
+
32
+ # Configure section title
33
+ exercise_section.prepend(child: section_title)
34
+ exercise_section.cut(to: exercise_clipboard)
35
+ end
36
+ end
37
+
38
+ return if exercise_clipboard.none?
39
+
40
+ @content = exercise_clipboard.paste
41
+
42
+ append_to_element = append_to || chapter
43
+ @in_composite_chapter = append_to_element.is?(:composite_chapter)
44
+
45
+ append_to_element.append(child: render(file:
46
+ '../../templates/eoc_section_title_template.xhtml.erb'))
47
+ end
48
+ end
49
+ end
@@ -2,12 +2,16 @@
2
2
 
3
3
  module Kitchen
4
4
  module Directions
5
- module BakeChapterAnswerKey
6
- def self.v1(chapter:, metadata_source:, strategy:, append_to:)
5
+ module MoveSolutionsToAnswerKey
6
+ def self.v1(chapter:, metadata_source:, strategy:, append_to:, strategy_options: {}, solutions_plural: true)
7
7
  V1.new.bake(
8
8
  chapter: chapter,
9
9
  metadata_source: metadata_source,
10
- strategy: strategy, append_to: append_to)
10
+ strategy: strategy,
11
+ append_to: append_to,
12
+ strategy_options: strategy_options,
13
+ solutions_plural: solutions_plural
14
+ )
11
15
  end
12
16
  end
13
17
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Kitchen::Directions::BakeChapterAnswerKey
3
+ module Kitchen::Directions::MoveSolutionsToAnswerKey
4
4
  module Strategies
5
5
  class Calculus
6
6
  def bake(chapter:, append_to:)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::MoveSolutionsToAnswerKey
4
+ module Strategies
5
+ class Default
6
+ def bake(chapter:, append_to:)
7
+ bake_section(chapter: chapter, append_to: append_to)
8
+ end
9
+
10
+ protected
11
+
12
+ def bake_section(chapter:, append_to:)
13
+ @classes.each do |klass|
14
+ chapter.search(".#{klass} [data-type='solution']").each do |solution|
15
+ append_to.add_child(solution.cut.to_s)
16
+ end
17
+ end
18
+ end
19
+
20
+ # This method helps to obtain more strategy-specific params through
21
+ # "strategy_options: {blah1: 1, blah2: 2}"
22
+ def initialize(strategy_options)
23
+ @classes = strategy_options[:classes] || (raise 'missing classes for strategy')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::MoveSolutionsToAnswerKey
4
+ module Strategies
5
+ class Precalculus
6
+ def bake(chapter:, append_to:)
7
+ try_note_solutions(chapter: chapter, append_to: append_to)
8
+
9
+ # Bake section exercises
10
+ chapter.non_introduction_pages.each do |page|
11
+ number = "#{chapter.count_in(:book)}.#{page.count_in(:chapter)}"
12
+ bake_section(chapter: page, append_to: append_to, klass: 'section-exercises',
13
+ number: number)
14
+ end
15
+
16
+ # Bake other types of exercises
17
+ classes = %w[review-exercises practice-test]
18
+ classes.each do |klass|
19
+ bake_section(chapter: chapter, append_to: append_to, klass: klass)
20
+ end
21
+ end
22
+
23
+ protected
24
+
25
+ def bake_section(chapter:, append_to:, klass:, number: nil)
26
+ section_solutions_set = Kitchen::Clipboard.new
27
+ chapter.search(".#{klass}").each do |section|
28
+ section.search('[data-type="solution"]').each do |solution|
29
+ solution.cut(to: section_solutions_set)
30
+ end
31
+ end
32
+
33
+ return if section_solutions_set.items.empty?
34
+
35
+ title = <<~HTML
36
+ <h3 data-type="title">
37
+ <span class="os-title-label">#{I18n.t(:"eoc.#{klass}", number: number)}</span>
38
+ </h3>
39
+ HTML
40
+
41
+ append_solution_area(title: title, solutions: section_solutions_set, append_to: append_to)
42
+ end
43
+
44
+ def try_note_solutions(chapter:, append_to:)
45
+ append_to.add_child(
46
+ <<~HTML
47
+ <div class="os-module-reset-solution-area os-try-solution-area">
48
+ <h3 data-type="title">
49
+ <span class="os-title-label">#{I18n.t(:"notes.try")}</span>
50
+ </h3>
51
+ </div>
52
+ HTML
53
+ )
54
+ chapter.non_introduction_pages.each do |page|
55
+ solutions = Kitchen::Clipboard.new
56
+ page.notes('$.try').each do |note|
57
+ note.exercises.each do |exercise|
58
+ solution = exercise.solution
59
+ solution&.cut(to: solutions) #if solution
60
+ end
61
+ end
62
+ next if solutions.items.empty?
63
+
64
+ title_snippet = Kitchen::Directions::EocSectionTitleLinkSnippet.v2(page: page)
65
+
66
+ append_solution_area(title: title_snippet, solutions: solutions,
67
+ append_to: append_to.search('.os-try-solution-area').first)
68
+ end
69
+ end
70
+
71
+ def append_solution_area(title:, solutions:, append_to:)
72
+ append_to = append_to.add_child(
73
+ <<~HTML
74
+ <div class="os-solution-area">
75
+ #{title}
76
+ </div>
77
+ HTML
78
+ ).first
79
+
80
+ append_to.add_child(solutions.paste)
81
+ end
82
+ end
83
+ end
84
+ end