openstax_kitchen 11.0.0 → 11.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/kitchen/composite_page_element.rb +8 -0
  5. data/lib/kitchen/directions/bake_chapter_introductions/bake_chapter_objectives.rb +46 -0
  6. data/lib/kitchen/directions/bake_chapter_introductions/bake_chapter_outline.rb +14 -0
  7. data/lib/kitchen/directions/bake_chapter_introductions/main.rb +43 -0
  8. data/lib/kitchen/directions/bake_chapter_introductions/v1.rb +56 -0
  9. data/lib/kitchen/directions/bake_chapter_introductions/v2.rb +91 -0
  10. data/lib/kitchen/directions/bake_custom_sections/main.rb +14 -0
  11. data/lib/kitchen/directions/bake_custom_sections/v1.rb +42 -0
  12. data/lib/kitchen/directions/bake_equations.rb +2 -3
  13. data/lib/kitchen/directions/bake_example.rb +4 -5
  14. data/lib/kitchen/directions/bake_figure.rb +5 -3
  15. data/lib/kitchen/directions/bake_iframes/main.rb +11 -0
  16. data/lib/kitchen/directions/bake_iframes/v1.rb +25 -0
  17. data/lib/kitchen/directions/bake_index/main.rb +2 -2
  18. data/lib/kitchen/directions/bake_index/v1.rb +39 -7
  19. data/lib/kitchen/directions/bake_index/v1.xhtml.erb +3 -3
  20. data/lib/kitchen/directions/bake_injected_exercise.rb +18 -0
  21. data/lib/kitchen/directions/bake_injected_exercise_question.rb +71 -0
  22. data/lib/kitchen/directions/bake_link_placeholders.rb +15 -2
  23. data/lib/kitchen/directions/bake_lists_with_para.rb +3 -3
  24. data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +5 -5
  25. data/lib/kitchen/directions/bake_notes/bake_note_subtitle.rb +6 -2
  26. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb +13 -3
  27. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb +29 -25
  28. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v2.rb +22 -17
  29. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +27 -22
  30. data/lib/kitchen/directions/bake_numbered_exercise/main.rb +3 -2
  31. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +6 -24
  32. data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +3 -3
  33. data/lib/kitchen/directions/bake_numbered_table/main.rb +4 -4
  34. data/lib/kitchen/directions/bake_numbered_table/v1.rb +3 -3
  35. data/lib/kitchen/directions/bake_numbered_table/v2.rb +3 -3
  36. data/lib/kitchen/directions/bake_toc.rb +1 -1
  37. data/lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_exercise_section.rb +1 -7
  38. data/lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_numbered_note.rb +1 -7
  39. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb +17 -0
  40. data/lib/kitchen/element_base.rb +38 -2
  41. data/lib/kitchen/element_enumerator_base.rb +35 -0
  42. data/lib/kitchen/injected_question_element.rb +77 -0
  43. data/lib/kitchen/injected_question_element_enumerator.rb +21 -0
  44. data/lib/kitchen/selectors/base.rb +6 -0
  45. data/lib/kitchen/selectors/standard_1.rb +3 -0
  46. data/lib/kitchen/solution_element_enumerator.rb +21 -0
  47. data/lib/kitchen/version.rb +1 -1
  48. data/lib/locales/en.yml +6 -4
  49. data/lib/locales/es.yml +5 -4
  50. data/lib/locales/pl.yml +52 -7
  51. metadata +17 -6
  52. data/lib/kitchen/directions/bake_chapter_introductions/chapter_introduction.xhtml.erb +0 -0
  53. data/lib/kitchen/directions/bake_chapter_introductions.rb +0 -65
  54. data/lib/kitchen/directions/bake_notes/bake_note_iframes.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6964a7fe85234e82e7f54f3b6d4980633f4f4c29c49d3123743c214d9f46653
4
- data.tar.gz: 2426f1990ae74d35d2ac098bcf7d5c09aa5094eeef598dd9658d8fedf97916c4
3
+ metadata.gz: 4340461612470e8ddff3976af6bf342821a18f1e01c70d5c6d4dcbf08636ac24
4
+ data.tar.gz: 293967ff3cf8af70f6d9d5f5d20866c77608af41c279590b3abb39966813f048
5
5
  SHA512:
6
- metadata.gz: faba0041d8c958c3ffa369dbe2d0c5453f8a236bedd0654e362afa65c84093ec22771dadaa9a313e688f6644681267b63f263ba60af9d1b81a211bc3c98a5df1
7
- data.tar.gz: a1e8ff40b3377508904ab62980302f129527755512f58506c805d7ae1507977ce65f1c993786cdeffc5f3871e4448e5d4df264979539d60f995d7f9c7b3ece48
6
+ metadata.gz: 70eedaaa535e97066b5b5b0d80e9c8916ffb6de5ecdf063f7a58d2c984253771742832278e53f5ce8bea3f0f3c7cbdd97da058258e5ace42dda0da372243ff2d
7
+ data.tar.gz: 72001901b5c82c46bd835521d9a815d178cc6bcea04502fd6b9b10bf36309ed42028b92714fd003e1a0042c60ce9eb4ab505dc627d8dd763f9c6892ff1fee7ea
data/CHANGELOG.md CHANGED
@@ -6,6 +6,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [11.1.0] - 2021-08-30
10
+
11
+ * Update injected questions to synthesize ids during baking (minor)
12
+ * Fix `BakeListsWithPara` to copy all children from para not just text (minor)
13
+ * Implement labels with cases to `BakeAutotitledNotes` and `BakeNumberedNotes` (minor)
14
+ * Add ids to injected questions (minor)
15
+ * Create `BakeIframes` outer directory to allow bake iframes also from outside notes, remove `BakeNoteIFrames` module from notes directory (minor)
16
+ * Update the contemporary math `Strategy` to target injected solution sections (minor)
17
+ * Update `BakeNumberedNotes` to handle injected questions in notes (minor)
18
+ * Create `InjectedQuestionElement` and `InjectedQuestionElementEnumerator` classes (minor)
19
+ * Create `BakeInjectedExercise` and `BakeInjectedExerciseQuestion` directions (minor)
20
+ * Update `MoveSolutionsFromExerciseSection` and `MoveSolutionsFromNumberedNote` to move injected solutions (minor)
21
+ * Add `SolutionElementEnumerator` to support the above (minor)
22
+ * Remove multipart exercise baking from `BakeNumberedExercise`; this is now done in `InjectedExercise` directions (patch)
23
+ * Modify target labels to use grammatical cases (minor)
24
+ * Modify `BakeIndex` to bake multiple types of indexes (minor)
25
+ * Create `v2` in `BakeChapterIntroductions` that should replace `v1` (minor)
26
+ * Added a DEPRECATION warning in `v1` for `BakeChapterIntroductions` (minor)
27
+ * Added a bit more description to deprecation warning for `BakeChapterIntroductions.v1` (minor)
28
+
9
29
  ## [11.0.0] - 2021-08-6
10
30
 
11
31
  * Add `ChangeSubsectionTitleTag` direction for modifying eoc sections (minor)
@@ -20,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
20
40
  * Adds `PageElement#count_in_chapter_without_intro_page` (minor)
21
41
  * Adds `ChapterElement#has_introduction?` (minor)
22
42
  * Adds `BakeFolio` to set spanish translation variables in the html tag for folio-pdf purposes (minor)
43
+ * Create `BakeCustomSections` direction for English Composition (minor)
23
44
  * Create `BakeAnnotationClasses` v1 for English Composition (minor)
24
45
 
25
46
  ## [10.0.0] - 2021-07-30
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openstax_kitchen (11.0.0)
4
+ openstax_kitchen (11.1.0)
5
5
  activesupport
6
6
  i18n
7
7
  nokogiri
@@ -41,6 +41,14 @@ module Kitchen
41
41
  has_class?('os-index-container')
42
42
  end
43
43
 
44
+ # Returns true if this page is a book index of type
45
+ #
46
+ # @return [Boolean]
47
+ #
48
+ def is_index_of_type?
49
+ (self[:class] || '').match?(/os-index-.+-container/)
50
+ end
51
+
44
52
  # In books we can find two types of EOB References.
45
53
  #
46
54
  # One of them has form similar to footnotes. There are citation links in the text that provides
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class BakeChapterObjectives
5
+ def bake(chapter:, strategy:)
6
+ case strategy
7
+ when :default
8
+ bake_as_note(chapter: chapter)
9
+ when :add_objectives
10
+ add_chapter_objectives(chapter: chapter)
11
+ when :none
12
+ ''
13
+ else
14
+ raise 'No such strategy'
15
+ end
16
+ end
17
+
18
+ def bake_as_note(chapter:)
19
+ chapter_objectives_note = chapter.notes('$.chapter-objectives').first
20
+
21
+ # trash existing title
22
+ chapter_objectives_note.titles.first&.trash
23
+ Kitchen::Directions::BakeAutotitledNotes.v1(
24
+ book: chapter,
25
+ classes: %w[chapter-objectives],
26
+ bake_subtitle: false
27
+ )
28
+
29
+ chapter_objectives_note.cut.paste
30
+ end
31
+
32
+ def add_chapter_objectives(chapter:)
33
+ chapter.non_introduction_pages.map do |page|
34
+ <<~HTML
35
+ <div class="os-chapter-objective">
36
+ <a class="os-chapter-objective" href="##{page.title[:id]}">
37
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
38
+ <span class="os-divider"> </span>
39
+ <span data-type="" itemprop="" class="os-text">#{page.title.children[0].text}</span>
40
+ </a>
41
+ </div>
42
+ HTML
43
+ end.join('')
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class BakeChapterOutline
5
+ def bake(chapter_objectives_html:)
6
+ <<~HTML
7
+ <div class="os-chapter-outline">
8
+ <h3 class="os-title">#{I18n.t(:chapter_outline)}</h3>
9
+ #{chapter_objectives_html}
10
+ </div>
11
+ HTML
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeChapterIntroductions
6
+ def self.v1(book:)
7
+ V1.new.bake(
8
+ book: book
9
+ )
10
+ end
11
+
12
+ def self.v2(
13
+ book:,
14
+ strategy_options: {
15
+ strategy: :default, bake_chapter_outline: false, introduction_order: :v1
16
+ }
17
+ )
18
+ V2.new.bake(
19
+ book: book,
20
+ strategy_options: strategy_options
21
+ )
22
+ end
23
+
24
+ def self.bake_chapter_objectives(chapter:, strategy:)
25
+ BakeChapterObjectives.new.bake(
26
+ chapter: chapter,
27
+ strategy: strategy
28
+ )
29
+ end
30
+
31
+ def self.bake_chapter_outline(chapter_objectives_html:)
32
+ BakeChapterOutline.new.bake(
33
+ chapter_objectives_html: chapter_objectives_html
34
+ )
35
+ end
36
+
37
+ def self.v1_update_selectors(something_with_selectors)
38
+ something_with_selectors.selectors.title_in_introduction_page =
39
+ ".intro-text > [data-type='document-title']"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class V1
5
+ def bake(book:)
6
+ # <b>DEPRECATED:</b> Please use <tt>v2</tt> instead.
7
+ warn '[DEPRECATION] `BakeChapterIntroductions.v1` is deprecated. Please use `v2` instead.'
8
+
9
+ book.chapters.each do |chapter|
10
+ introduction_page = chapter.introduction_page
11
+
12
+ introduction_page.search("div[data-type='description']").trash
13
+ introduction_page.search("div[data-type='abstract']").trash
14
+
15
+ title = introduction_page.title.cut
16
+ title.name = 'h2'
17
+ Kitchen::Directions::MoveTitleTextIntoSpan.v1(title: title)
18
+
19
+ intro_content = introduction_page.search(
20
+ "> :not([data-type='metadata']):not(.splash):not(.has-splash)"
21
+ ).cut
22
+
23
+ chapter_objectives_html = chapter.non_introduction_pages.map do |page|
24
+ <<~HTML
25
+ <div class="os-chapter-objective">
26
+ <a class="os-chapter-objective" href="##{page.title[:id]}">
27
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
28
+ <span class="os-divider"> </span>
29
+ <span data-type="" itemprop="" class="os-text">#{page.title.children[0].text}</span>
30
+ </a>
31
+ </div>
32
+ HTML
33
+ end.join('')
34
+
35
+ chapter_outline =
36
+ Kitchen::Directions::BakeChapterIntroductions.bake_chapter_outline(
37
+ chapter_objectives_html: chapter_objectives_html
38
+ )
39
+
40
+ introduction_page.append(child:
41
+ <<~HTML
42
+ <div class="intro-body">
43
+ #{chapter_outline}
44
+ <div class="intro-text">
45
+ #{title.paste}
46
+ #{intro_content.paste}
47
+ </div>
48
+ </div>
49
+ HTML
50
+ )
51
+ end
52
+
53
+ Kitchen::Directions::BakeChapterIntroductions.v1_update_selectors(book)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class V2
5
+ def bake(book:, strategy_options:)
6
+ book.chapters.each do |chapter|
7
+ introduction_page = chapter.introduction_page
8
+ title = bake_title(introduction_page: introduction_page)
9
+
10
+ chapter_intro_html =
11
+ Kitchen::Directions::BakeChapterIntroductions.bake_chapter_objectives(
12
+ chapter: chapter,
13
+ strategy: strategy_options[:strategy]
14
+ )
15
+
16
+ if strategy_options[:bake_chapter_outline]
17
+ chapter_intro_html =
18
+ Kitchen::Directions::BakeChapterIntroductions.bake_chapter_outline(
19
+ chapter_objectives_html: chapter_intro_html
20
+ )
21
+ end
22
+
23
+ case strategy_options[:introduction_order]
24
+ when :v1
25
+ v1_introduction_order(
26
+ introduction_page: introduction_page,
27
+ chapter_intro_html: chapter_intro_html,
28
+ title: title
29
+ )
30
+ when :v2
31
+ v2_introduction_order(
32
+ introduction_page: introduction_page,
33
+ chapter_intro_html: chapter_intro_html,
34
+ title: title
35
+ )
36
+ end
37
+ end
38
+
39
+ Kitchen::Directions::BakeChapterIntroductions.v1_update_selectors(book)
40
+ end
41
+
42
+ def v1_introduction_order(introduction_page:, chapter_intro_html:, title:)
43
+ intro_content = introduction_page.search(
44
+ "> :not([data-type='metadata']):not(.splash):not(.has-splash)"
45
+ ).cut
46
+
47
+ introduction_page.append(child:
48
+ <<~HTML
49
+ <div class="intro-body">
50
+ #{chapter_intro_html}
51
+ <div class="intro-text">
52
+ #{title.paste}
53
+ #{intro_content.paste}
54
+ </div>
55
+ </div>
56
+ HTML
57
+ )
58
+ end
59
+
60
+ def v2_introduction_order(introduction_page:, chapter_intro_html:, title:)
61
+ if chapter_intro_html.empty?
62
+ chapter_intro_html = introduction_page.notes('$.chapter-objectives').first&.cut&.paste
63
+ end
64
+ extra_content = introduction_page.search(
65
+ '> :not([data-type="metadata"]):not(.splash):not(.has-splash)'
66
+ ).cut
67
+
68
+ introduction_page.append(child:
69
+ <<~HTML
70
+ <div class="intro-body">
71
+ #{chapter_intro_html}
72
+ <div class="intro-text">
73
+ #{title.paste}
74
+ #{extra_content.paste}
75
+ </div>
76
+ </div>
77
+ HTML
78
+ )
79
+ end
80
+
81
+ def bake_title(introduction_page:)
82
+ introduction_page.search(
83
+ 'div[data-type="description"], div[data-type="abstract"]'
84
+ ).each(&:trash)
85
+
86
+ title = introduction_page.title.cut
87
+ title.name = 'h2'
88
+ Kitchen::Directions::MoveTitleTextIntoSpan.v1(title: title)
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeCustomSections
6
+ def self.v1(chapter:, custom_sections_properties:)
7
+ V1.new.bake(
8
+ chapter: chapter,
9
+ custom_sections_properties: custom_sections_properties
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeCustomSections
4
+ class V1
5
+ def bake(chapter:, custom_sections_properties:)
6
+ custom_sections_properties.each do |_custom_section_name, property|
7
+ title_text = I18n.t(:"custom-sections.#{property[:class]}")
8
+ property_class = property[:class]
9
+ inject = property[:inject]
10
+ chapter.search(".#{property_class}").each do |custom_section|
11
+
12
+ case inject
13
+ when 'title'
14
+ custom_section_title = custom_section.first('h2')
15
+ custom_section_title_os_text = custom_section_title.first('.os-text')
16
+ custom_section_title_sibling = custom_section.first('h2 + div')
17
+ div_id = custom_section_title_sibling['id']
18
+ custom_section_title_sibling.trash
19
+ custom_section_title.append(sibling:
20
+ <<~HTML
21
+ <h3 class="os-subtitle" id="#{div_id}">#{custom_section_title_os_text.text}</h3>
22
+ HTML
23
+ )
24
+ custom_section_title_os_text.replace_children(with: title_text)
25
+ when 'subtitle'
26
+ custom_section_title = custom_section.titles.first
27
+ custom_section_title.name = 'h4'
28
+ custom_section_title.prepend(sibling:
29
+ <<~HTML
30
+ <h3 class="os-title">#{title_text}</h3>
31
+ HTML
32
+ )
33
+ when 'title_prefix'
34
+ custom_section_title = custom_section.titles.first
35
+ custom_section_title.replace_children(with: "#{title_text}: " +
36
+ custom_section_title.text)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -3,14 +3,13 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeEquations
6
- def self.v1(book:, number_decorator: :none)
6
+ def self.v1(book:, number_decorator: :none, cases: false)
7
7
  book.chapters.search('div[data-type="equation"]:not(.unnumbered)').each do |eq|
8
8
  chapter = eq.ancestor(:chapter)
9
9
  number = "#{chapter.count_in(:book)}.#{eq.count_in(:chapter)}"
10
10
 
11
11
  # Store label information
12
- equation_label = "#{I18n.t(:equation)} #{number}"
13
- book.pantry(name: :link_text).store equation_label, label: eq.id
12
+ eq.target_label(label_text: 'equation', custom_content: number, cases: cases)
14
13
 
15
14
  decorated_number =
16
15
  case number_decorator
@@ -3,22 +3,21 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeExample
6
- def self.v1(example:, number:, title_tag:, numbered_solutions: false)
6
+ def self.v1(example:, number:, title_tag:, numbered_solutions: false, cases: false)
7
7
  example.wrap_children(class: 'body')
8
8
 
9
9
  example.prepend(child:
10
10
  <<~HTML
11
11
  <#{title_tag} class="os-title">
12
- <span class="os-title-label">#{I18n.t(:example_label)} </span>
12
+ <span class="os-title-label">#{I18n.t("example#{'.nominative' if cases}")} </span>
13
13
  <span class="os-number">#{number}</span>
14
14
  <span class="os-divider"> </span>
15
15
  </#{title_tag}>
16
16
  HTML
17
17
  )
18
18
 
19
- example.document
20
- .pantry(name: :link_text)
21
- .store("#{I18n.t(:example_label)} #{number}", label: example.id)
19
+ # Store label information
20
+ example.target_label(label_text: 'example', custom_content: number, cases: cases)
22
21
 
23
22
  example.titles_to_rename.each do |title|
24
23
  title.name = 'h4'
@@ -3,7 +3,7 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeFigure
6
- def self.v1(figure:, number:)
6
+ def self.v1(figure:, number:, cases: false)
7
7
  return if figure.has_class?('unnumbered') && !figure.has_class?('splash')
8
8
 
9
9
  figure.wrap(%(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
@@ -19,14 +19,16 @@ module Kitchen
19
19
  return
20
20
  end
21
21
 
22
- figure.pantry(name: :link_text).store "#{I18n.t(:figure)} #{number}", label: figure.id
22
+ # Store label information
23
+ figure.target_label(label_text: 'figure', custom_content: number, cases: cases)
24
+
23
25
  title = figure.title&.cut
24
26
 
25
27
  caption = figure.caption&.cut
26
28
  figure.append(sibling:
27
29
  <<~HTML
28
30
  <div class="os-caption-container">
29
- <span class="os-title-label">#{I18n.t(:figure)} </span>
31
+ <span class="os-title-label">#{I18n.t("figure#{'.nominative' if cases}")} </span>
30
32
  <span class="os-number">#{number}</span>
31
33
  <span class="os-divider"> </span>
32
34
  #{"<span class=\"os-title\" data-type=\"title\" id=\"#{title.id}\">#{title.children}</span>" if title}