openstax_kitchen 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -3
  3. data/Gemfile.lock +1 -1
  4. data/README.md +7 -0
  5. data/lib/kitchen/directions/bake_book_answer_key/eob_solutions_container.xhtml.erb +9 -0
  6. data/lib/kitchen/directions/bake_book_answer_key/main.rb +11 -0
  7. data/lib/kitchen/directions/bake_book_answer_key/v1.rb +13 -0
  8. data/lib/kitchen/directions/bake_chapter_answer_key/main.rb +14 -0
  9. data/lib/kitchen/directions/bake_chapter_answer_key/strategies/calculus.rb +41 -0
  10. data/lib/kitchen/directions/bake_chapter_answer_key/strategies/uphysics.rb +61 -0
  11. data/lib/kitchen/directions/bake_chapter_answer_key/v1.rb +32 -0
  12. data/lib/kitchen/directions/bake_chapter_glossary.rb +4 -2
  13. data/lib/kitchen/directions/bake_chapter_key_concepts/key_concepts.xhtml.erb +16 -0
  14. data/lib/kitchen/directions/bake_chapter_key_concepts/main.rb +11 -0
  15. data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +30 -0
  16. data/lib/kitchen/directions/bake_chapter_key_equations.rb +4 -2
  17. data/lib/kitchen/directions/bake_chapter_review/chapter_review.xhtml.erb +9 -0
  18. data/lib/kitchen/directions/bake_chapter_review/main.rb +11 -0
  19. data/lib/kitchen/directions/bake_chapter_review/v1.rb +13 -0
  20. data/lib/kitchen/directions/bake_chapter_review_exercises/main.rb +15 -0
  21. data/lib/kitchen/directions/bake_chapter_review_exercises/review_exercises.xhtml.erb +10 -0
  22. data/lib/kitchen/directions/bake_chapter_review_exercises/v1.rb +38 -0
  23. data/lib/kitchen/directions/bake_chapter_review_exercises/v2.rb +50 -0
  24. data/lib/kitchen/directions/bake_chapter_section_exercises/main.rb +11 -0
  25. data/lib/kitchen/directions/bake_chapter_section_exercises/v1.rb +28 -0
  26. data/lib/kitchen/directions/bake_chapter_summary.rb +1 -1
  27. data/lib/kitchen/directions/bake_checkpoint.rb +44 -0
  28. data/lib/kitchen/directions/bake_composite_chapters.rb +14 -0
  29. data/lib/kitchen/directions/bake_equations.rb +27 -0
  30. data/lib/kitchen/directions/bake_example.rb +29 -7
  31. data/lib/kitchen/directions/bake_exercises/main.rb +1 -0
  32. data/lib/kitchen/directions/bake_exercises/v1.rb +34 -31
  33. data/lib/kitchen/directions/bake_non_introduction_pages.rb +26 -0
  34. data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +29 -0
  35. data/lib/kitchen/directions/bake_notes/bake_note_subtitle.rb +18 -0
  36. data/lib/kitchen/directions/{bake_notes.rb → bake_notes/bake_notes.rb} +6 -16
  37. data/lib/kitchen/directions/bake_notes/bake_numbered_notes.rb +63 -0
  38. data/lib/kitchen/directions/bake_notes/bake_unclassified_notes.rb +30 -0
  39. data/lib/kitchen/directions/bake_numbered_exercise/main.rb +11 -0
  40. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +34 -0
  41. data/lib/kitchen/directions/bake_numbered_table/main.rb +2 -2
  42. data/lib/kitchen/directions/bake_numbered_table/v1.rb +17 -3
  43. data/lib/kitchen/directions/bake_page_abstracts.rb +16 -0
  44. data/lib/kitchen/directions/bake_problem_first_elements.rb +16 -0
  45. data/lib/kitchen/directions/bake_stepwise.rb +1 -5
  46. data/lib/kitchen/directions/bake_theorem/main.rb +11 -0
  47. data/lib/kitchen/directions/bake_theorem/v1.rb +28 -0
  48. data/lib/kitchen/directions/bake_toc.rb +6 -0
  49. data/lib/kitchen/directions/eoc_section_title_link_snippet.rb +20 -0
  50. data/lib/kitchen/element_base.rb +40 -1
  51. data/lib/kitchen/element_enumerator_base.rb +87 -8
  52. data/lib/kitchen/exercise_element.rb +45 -0
  53. data/lib/kitchen/exercise_element_enumerator.rb +21 -0
  54. data/lib/kitchen/note_element.rb +17 -16
  55. data/lib/kitchen/page_element.rb +8 -0
  56. data/lib/kitchen/recipe.rb +35 -2
  57. data/lib/kitchen/version.rb +1 -1
  58. data/lib/locales/en.yml +9 -7
  59. data/lib/locales/pl.yml +24 -0
  60. data/lib/openstax_kitchen.rb +1 -1
  61. metadata +39 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f404296c40eba5dbfdeeb4c4de0d11492eb327e94d49c96689b262a03bc838de
4
- data.tar.gz: b97faf532e7e098dba23ef1d1f3c42ca7c051d7fc6ad8351fa6b20209cb99ddd
3
+ metadata.gz: 994e6a3d5161afbcd853fe2b432e7aeb80bf2390d4d7b7ae8463e6da8ce21f15
4
+ data.tar.gz: 7c276963aaa777b1e6116b98a9af0659f8b4e9c1491a3fe968bd9f15fc46f61c
5
5
  SHA512:
6
- metadata.gz: 7f8e774352355cc44b01765b101e97db3128e19e7416a6d5138d0a83db4378e7910d196e42849237e2130c6f7463db6f13679d53ac666b6a0abf6f867ecf6a36
7
- data.tar.gz: 84fece5f5d36f16324022d3ca34b6827f6549bed21551caedbb2845ff41d5b7b1f4b47c8e07a6fac6b14ed2e5f092435b63618a3b9e0f925a40cda21b04babfb
6
+ metadata.gz: a0041d04e8a1e39295c21ed0884db3e1b838edac90c7c317409b3499e1e2d5744450d26ccb1518a55c7cf6ec39a35b278e03781b8f9933486d789583b9c39bdd
7
+ data.tar.gz: f9207ee80e17ae3035d2c29cca11f4d59e10afc7193e73f751763fb27987477e7cffcc914166927d196484c0c82767d3c1302bca92a64098d4eb2674edb83843
data/CHANGELOG.md CHANGED
@@ -6,6 +6,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.1.0] - 2021-04-19
10
+
11
+ * Add the ability to copy an element's ID to `ElementBase` (minor)
12
+ * Create `pl.yml` and add pl to available locals in `StubHelpers` module (minor)
13
+ * Add to `BakeNumberedNotes` directions for baking exercises in a note (with this comes removing bake checkpoints and theorems)
14
+ * Add `BakeEquations` direction (minor)
15
+ * Remove `NoteElement` logging (minor)
16
+ * Adds `BakeChapterReviewExercises` v2 and a u-physics `Strategy` to `BakeChapterAnswerKey` to support baking exercises in u-physics (minor)
17
+ * Have deprecated directions log a warning (minor)
18
+ * Added `wrap_children` method on elements (minor)
19
+ * Refactored `NoteElement` to infer the note title from book-specific locales (minor)
20
+ * Added support for a recipe to infer or be given a book-specific locale file (minor)
21
+ * Added `NumberedTable` support for titles and always captions (minor)
22
+ * Added titles method to `ElementEnumeratorBase` and `ElementBase` (minor)
23
+ * Added a file for baking composite chapters called (`bake_composite_chapters`) and the respective spec.
24
+ (minor change)
25
+ * Added `BakeProblemFirstElements` direction (minor)
26
+
9
27
  ## [3.0.0] - 2021-03-17
10
28
 
11
29
  * Added a subfigure? method to `FigureElements`(minor)
@@ -19,11 +37,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
19
37
  * Added ability to filter searches based on `only` and `except` conditions, which can be names of element methods or blocks of code (minor)
20
38
  * Changed from tracking and using `css_or_xpath` strings and arrays to `search_query` objects that
21
39
  wrap `css_or_xpath` variables along with `only` and `except` conditions. (major?)
40
+ * Refactored bake_exercises to better support parallel work on multiple versions. (minor)
22
41
 
23
42
  ## [2.0.0] - 2020-12-18
24
-
25
- * Refactored bake_exercises to better support parallel work on multiple versions.
26
- (minor change) Does not affect existing recipes.
43
+ * Added a file for baking key concepts called (`bake_chapter_key_concepts`) and the respective specs.
44
+ (minor change) only affects the book if called from the recipe
27
45
  * Changed the main gem source file to have the same name as the gem (`openstax_kitchen`) so that you don't have to `require` a different name than you use in your `gem` call.
28
46
 
29
47
  ## [1.0.0] - 2020-12-15
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openstax_kitchen (3.0.0)
4
+ openstax_kitchen (3.1.0)
5
5
  activesupport
6
6
  i18n
7
7
  nokogiri
data/README.md CHANGED
@@ -210,6 +210,13 @@ And we can wrap an element with another element:
210
210
  doc.search("span").first.wrap("<span class='other'>")
211
211
  ```
212
212
 
213
+ or wrap an element's children:
214
+
215
+ ```ruby
216
+ # <div><span>Hi</span></div> => <div><span><span class="other" data-type="foo">Hi</span></span></div>
217
+ doc.search("span").first.wrap_children('span', class: 'other', data_type: 'foo')
218
+ ```
219
+
213
220
  ### Checking for elements
214
221
 
215
222
  You can see if an element contains an element matching a selector:
@@ -0,0 +1,9 @@
1
+ <div class="os-eob os-solutions-container" data-type="composite-chapter" data-uuid-key=".solutions">
2
+ <h1 data-type="document-title">
3
+ <span class="os-text"><%= I18n.t(:eoc_answer_key_title) %></span>
4
+ </h1>
5
+ <div data-type="metadata" style="display: none;">
6
+ <h1 data-type="document-title" itemprop="name"><%= I18n.t(:eoc_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 BakeBookAnswerKey
6
+ def self.v1(book:)
7
+ V1.new.bake(book: book)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeBookAnswerKey
4
+ class V1
5
+ renderable
6
+
7
+ def bake(book:)
8
+ @metadata = book.metadata.children_to_keep.copy
9
+ book.body.append(child: render(file: 'eob_solutions_container.xhtml.erb'))
10
+ book.body.first('.os-eob.os-solutions-container')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeChapterAnswerKey
6
+ def self.v1(chapter:, metadata_source:, strategy:, append_to:)
7
+ V1.new.bake(
8
+ chapter: chapter,
9
+ metadata_source: metadata_source,
10
+ strategy: strategy, append_to: append_to)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterAnswerKey
4
+ module Strategies
5
+ class Calculus
6
+ def bake(chapter:, append_to:)
7
+ checkpoint_solutions = chapter.search('.checkpoint [data-type="solution"]').cut
8
+ append_solution_area(I18n.t(:checkpoint), checkpoint_solutions, append_to)
9
+
10
+ chapter.search('.section-exercises').each do |section|
11
+ section_solutions = section.search('[data-type="solution"]').cut
12
+ section_title = I18n.t(
13
+ :section_exercises,
14
+ number: "#{chapter.count_in(:book)}.#{section.count_in(:chapter)}"
15
+ )
16
+ append_solution_area(section_title, section_solutions, append_to)
17
+ end
18
+
19
+ chapter.search('.review-exercises').each do |section|
20
+ section_solutions = section.search('[data-type="solution"]').cut
21
+ append_solution_area(I18n.t(:review_exercises), section_solutions, append_to)
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def append_solution_area(title, clipboard, append_to)
28
+ append_to.add_child(
29
+ <<~HTML
30
+ <div class="os-solution-area">
31
+ <h3 data-type="title">
32
+ <span class="os-title-label">#{title}</span>
33
+ </h3>
34
+ #{clipboard.paste}
35
+ </div>
36
+ HTML
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterAnswerKey
4
+ module Strategies
5
+ class UPhysics
6
+ def bake(chapter:, append_to:)
7
+ bake_from_notes(chapter: chapter, append_to: append_to, klass: 'check-understanding')
8
+
9
+ classes = %w[review-conceptual-questions review-problems review-additional-problems
10
+ review-challenge]
11
+ classes.each do |klass|
12
+ bake_section(chapter: chapter, append_to: append_to, klass: klass)
13
+ end
14
+ end
15
+
16
+ protected
17
+
18
+ def bake_section(chapter:, append_to:, klass:)
19
+ section_solutions_set = []
20
+ chapter.search(".#{klass}").each do |section|
21
+ section.search('[data-type="solution"]').each do |solution|
22
+ section_solutions_set.push(solution.cut)
23
+ end
24
+ end
25
+
26
+ return if section_solutions_set.empty?
27
+
28
+ title = I18n.t(:"eoc.#{klass}")
29
+ append_solution_area(title, section_solutions_set, append_to)
30
+ end
31
+
32
+ def bake_from_notes(chapter:, append_to:, klass:)
33
+ solutions = []
34
+ chapter.notes(".#{klass}").each do |note|
35
+ solution = note.exercises.first.solution
36
+ solutions.push(solution.cut) if solution
37
+ end
38
+ return if solutions.empty?
39
+
40
+ title = I18n.t(:"notes.#{klass}")
41
+ append_solution_area(title, solutions, append_to)
42
+ end
43
+
44
+ def append_solution_area(title, solutions, append_to)
45
+ append_to = append_to.add_child(
46
+ <<~HTML
47
+ <div class="os-solution-area">
48
+ <h3 data-type="title">
49
+ <span class="os-title-label">#{title}</span>
50
+ </h3>
51
+ </div>
52
+ HTML
53
+ ).first
54
+
55
+ solutions.each do |solution|
56
+ append_to.add_child(solution.raw)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterAnswerKey
4
+ class V1
5
+ def bake(chapter:, metadata_source:, strategy:, append_to:)
6
+ strategy =
7
+ case strategy
8
+ when :calculus
9
+ Strategies::Calculus
10
+ when :uphysics
11
+ Strategies::UPhysics
12
+ else
13
+ raise 'No such strategy'
14
+ end
15
+
16
+ append_to.append(child:
17
+ <<~HTML
18
+ <div class="os-eob os-solutions-container" data-type="composite-page" data-uuid-key=".solutions#{chapter.count_in(:book)}">
19
+ <h2 data-type="document-title">
20
+ <span class="os-text">#{I18n.t(:chapter)} #{chapter.count_in(:book)}</span>
21
+ </h2>
22
+ <div data-type="metadata" style="display: none;">
23
+ <h1 data-type="document-title" itemprop="name">#{I18n.t(:chapter)} #{chapter.count_in(:book)}</h1>
24
+ #{metadata_source.children_to_keep.copy.paste}
25
+ </div>
26
+ </div>
27
+ HTML
28
+ )
29
+ strategy.new.bake(chapter: chapter, append_to: append_to.last_element)
30
+ end
31
+ end
32
+ end
@@ -5,7 +5,7 @@ module Kitchen
5
5
  # Bake directons for eoc glossary
6
6
  #
7
7
  module BakeChapterGlossary
8
- def self.v1(chapter:, metadata_source:)
8
+ def self.v1(chapter:, metadata_source:, append_to: nil)
9
9
  metadata_elements = metadata_source.children_to_keep.copy
10
10
 
11
11
  definitions = chapter.glossaries.search('dl').cut
@@ -17,7 +17,9 @@ module Kitchen
17
17
 
18
18
  return if definitions.none?
19
19
 
20
- chapter.append(child:
20
+ append_to_element = append_to || chapter
21
+
22
+ append_to_element.append(child:
21
23
  <<~HTML
22
24
  <div class="os-eoc os-glossary-container" data-type="composite-page" data-uuid-key="glossary">
23
25
  <h2 data-type="document-title">
@@ -0,0 +1,16 @@
1
+ <div class="os-eoc os-key-concepts-container" data-type="composite-page" data-uuid-key=".key-concepts">
2
+ <h2 data-type="document-title">
3
+ <span class="os-text"><%= I18n.t(:eoc_key_concepts) %></span>
4
+ </h2>
5
+ <div data-type="metadata" style="display: none;">
6
+ <h1 data-type="document-title" itemprop="name"><%= I18n.t(:eoc_key_concepts) %></h1>
7
+ <%= @metadata_elements.paste %>
8
+ </div>
9
+ <div class="os-key-concepts">
10
+ <% @key_concepts.each do |key_concept| %>
11
+ <div class="os-section-area">
12
+ <%= key_concept %>
13
+ </div>
14
+ <% end %>
15
+ </div>
16
+ </div>
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeChapterKeyConcepts
6
+ def self.v1(chapter:, metadata_source:, append_to: nil)
7
+ V1.new.bake(chapter: chapter, metadata_source: metadata_source, append_to: append_to)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterKeyConcepts
4
+ class V1
5
+ renderable
6
+ def bake(chapter:, metadata_source:, append_to:)
7
+ @metadata_elements = metadata_source.children_to_keep.copy
8
+
9
+ @key_concepts = []
10
+ key_concepts_clipboard = Kitchen::Clipboard.new
11
+ chapter.non_introduction_pages.each do |page|
12
+ key_concepts = page.key_concepts
13
+ next if key_concepts.none?
14
+
15
+ key_concepts.search('h3').trash
16
+ title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
17
+ key_concepts.each do |key_concept|
18
+ key_concept.prepend(child: title)
19
+ key_concept&.cut(to: key_concepts_clipboard)
20
+ end
21
+ @key_concepts.push(key_concepts_clipboard.paste)
22
+ key_concepts_clipboard.clear
23
+ end
24
+
25
+ append_to_element = append_to || chapter
26
+
27
+ append_to_element.append(child: render(file: 'key_concepts.xhtml.erb'))
28
+ end
29
+ end
30
+ end
@@ -5,7 +5,7 @@ module Kitchen
5
5
  # Bake directions for eoc key equations
6
6
  #
7
7
  module BakeChapterKeyEquations
8
- def self.v1(chapter:, metadata_source:)
8
+ def self.v1(chapter:, metadata_source:, append_to: nil)
9
9
  metadata_elements = metadata_source.children_to_keep.copy
10
10
 
11
11
  chapter.key_equations.search('h3').trash
@@ -13,7 +13,9 @@ module Kitchen
13
13
 
14
14
  return if key_equations.none?
15
15
 
16
- chapter.append(child:
16
+ append_to_element = append_to || chapter
17
+
18
+ append_to_element.append(child:
17
19
  <<~HTML
18
20
  <div class="os-eoc os-key-equations-container" data-type="composite-page" data-uuid-key=".key-equations">
19
21
  <h2 data-type="document-title">
@@ -0,0 +1,9 @@
1
+ <div class="os-eoc os-chapter-review-container" data-type="composite-chapter" data-uuid-key=".chapter-review">
2
+ <h2 data-type="document-title">
3
+ <span class="os-text"><%= I18n.t(:eoc_chapter_review) %></span>
4
+ </h2>
5
+ <div data-type="metadata" style="display: none;">
6
+ <h1 data-type="document-title" itemprop="name"><%= I18n.t(:eoc_chapter_review) %></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 BakeChapterReview
6
+ def self.v1(chapter:, metadata_source:)
7
+ V1.new.bake(chapter: chapter, metadata_source: metadata_source)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterReview
4
+ class V1
5
+ renderable
6
+
7
+ def bake(chapter:, metadata_source:)
8
+ @metadata = metadata_source.children_to_keep.copy
9
+ chapter.append(child: render(file: 'chapter_review.xhtml.erb'))
10
+ chapter.first('.os-eoc.os-chapter-review-container')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeChapterReviewExercises
6
+ def self.v1(chapter:, metadata_source:, append_to:, klass:)
7
+ V1.new.bake(chapter: chapter, metadata_source: metadata_source, append_to: append_to, klass: klass)
8
+ end
9
+
10
+ def self.v2(chapter:, metadata_source:, append_to:, klass:)
11
+ V2.new.bake(chapter: chapter, metadata_source: metadata_source, append_to: append_to, klass: klass)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ <div class="os-eoc os-<%=@klass%>-container" data-type="composite-page" data-uuid-key=".<%=@klass%>">
2
+ <h3 data-type="document-title">
3
+ <span class="os-text"><%= @title %></span>
4
+ </h3>
5
+ <div data-type="metadata" style="display: none;">
6
+ <h1 data-type="document-title" itemprop="name"><%= I18n.t(:eoc_exercises_title) %></h1>
7
+ <%= @metadata.paste %>
8
+ </div>
9
+ <%= @content %>
10
+ </div>