openstax_kitchen 10.0.0 → 11.0.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/Gemfile.lock +2 -2
  4. data/lib/kitchen/chapter_element.rb +8 -0
  5. data/lib/kitchen/directions/bake_annotation_classes/main.rb +12 -0
  6. data/lib/kitchen/directions/bake_annotation_classes/v1.rb +32 -0
  7. data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +0 -1
  8. data/lib/kitchen/directions/bake_chapter_references/v1.rb +1 -3
  9. data/lib/kitchen/directions/bake_chapter_summary.rb +1 -1
  10. data/lib/kitchen/directions/bake_eoc_section_content/change_subsection_title_tag.rb +13 -0
  11. data/lib/kitchen/directions/bake_example.rb +2 -0
  12. data/lib/kitchen/directions/bake_first_elements.rb +7 -3
  13. data/lib/kitchen/directions/bake_folio.rb +12 -0
  14. data/lib/kitchen/directions/bake_free_response/v1.rb +1 -1
  15. data/lib/kitchen/directions/bake_further_research.rb +1 -2
  16. data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +57 -16
  17. data/lib/kitchen/directions/bake_numbered_table/v1.rb +1 -1
  18. data/lib/kitchen/directions/bake_numbered_table/v2.rb +2 -2
  19. data/lib/kitchen/directions/bake_unit_page_title/v1.rb +4 -2
  20. data/lib/kitchen/directions/eoc_section_title_link_snippet.rb +32 -21
  21. data/lib/kitchen/directions/move_custom_section_to_eoc_container/main.rb +1 -3
  22. data/lib/kitchen/directions/move_custom_section_to_eoc_container/v1.rb +2 -2
  23. data/lib/kitchen/directions/move_exercises_to_eoc/v1.rb +1 -2
  24. data/lib/kitchen/directions/move_exercises_to_eoc/v2.rb +0 -1
  25. data/lib/kitchen/directions/move_exercises_to_eoc/v3.rb +1 -2
  26. data/lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_exercise_section.rb +40 -0
  27. data/lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_numbered_note.rb +33 -0
  28. data/lib/kitchen/directions/move_solutions_to_answer_key/solution_area_snippet.rb +12 -0
  29. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/calculus.rb +1 -1
  30. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb +4 -21
  31. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb +1 -1
  32. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/precalculus.rb +18 -39
  33. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/uphysics.rb +6 -48
  34. data/lib/kitchen/directions/move_solutions_to_answer_key/v1.rb +3 -2
  35. data/lib/kitchen/element_base.rb +0 -4
  36. data/lib/kitchen/page_element.rb +12 -1
  37. data/lib/kitchen/table_element.rb +25 -0
  38. data/lib/kitchen/version.rb +1 -1
  39. data/lib/locales/en.yml +3 -0
  40. data/lib/locales/es.yml +3 -0
  41. metadata +9 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a071ba6e289c222a7333f401c7d6bd25d6dba9527253b6c6ae123169d9b6425
4
- data.tar.gz: 2debc535f61a289f6668019f1eeb5cd639efaf8d49172d668f8b602e02e91b07
3
+ metadata.gz: e6964a7fe85234e82e7f54f3b6d4980633f4f4c29c49d3123743c214d9f46653
4
+ data.tar.gz: 2426f1990ae74d35d2ac098bcf7d5c09aa5094eeef598dd9658d8fedf97916c4
5
5
  SHA512:
6
- metadata.gz: 6bfeae3a664c95c17249ab32a8bba863091fb1e23f501273fd57d9752688c29ba9877b5a6404393dc88ae993f16af3f89fa768e3984cf81233908ab238b0350a
7
- data.tar.gz: '086fa06f8f7eb33f3908c15ba0172a02a1738c943ba87b25245f63626cda51e5163edbece95cdce2ce1907d5815aefd179db7fb7e3a4fe2a7165c623c5120ede'
6
+ metadata.gz: faba0041d8c958c3ffa369dbe2d0c5453f8a236bedd0654e362afa65c84093ec22771dadaa9a313e688f6644681267b63f263ba60af9d1b81a211bc3c98a5df1
7
+ data.tar.gz: a1e8ff40b3377508904ab62980302f129527755512f58506c805d7ae1507977ce65f1c993786cdeffc5f3871e4448e5d4df264979539d60f995d7f9c7b3ece48
data/CHANGELOG.md CHANGED
@@ -6,6 +6,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [11.0.0] - 2021-08-6
10
+
11
+ * Add `ChangeSubsectionTitleTag` direction for modifying eoc sections (minor)
12
+ * Add `MoveSolutionsFromNumberedNote`, `MoveSolutionsFromExerciseSection`, and `SolutionAreaSnippet` for answer key baking (minor)
13
+ * Refactor the following `Strategies`: contemporary math, precalculus, uphysics (minor)
14
+ * Fix `BakeUnitPageTite` to utilize only pages which are direct children of the unit (patch)
15
+ * Patch `BakeFirstElements` to include first figure elements (patch)
16
+ * Refactor `MoveCustomSectionToEocContainer` to remove `include_intro_page` (major)
17
+ * Update `BakeFirstElement` to optionally add the `has-first-inline-element` class (patch)
18
+ * Patch `BakeExample` crashing if an example has commentary but no title (patch)
19
+ * Refactor `EocSectionTitleLinkSnippet` to only have v1 with optional params (major)
20
+ * Adds `PageElement#count_in_chapter_without_intro_page` (minor)
21
+ * Adds `ChapterElement#has_introduction?` (minor)
22
+ * Adds `BakeFolio` to set spanish translation variables in the html tag for folio-pdf purposes (minor)
23
+ * Create `BakeAnnotationClasses` v1 for English Composition (minor)
24
+
9
25
  ## [10.0.0] - 2021-07-30
10
26
 
11
27
  * Add support for baking multipart questions to `BakeNumberedExercise` (minor)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openstax_kitchen (10.0.0)
4
+ openstax_kitchen (11.0.0)
5
5
  activesupport
6
6
  i18n
7
7
  nokogiri
@@ -99,7 +99,7 @@ GEM
99
99
  tins (~> 1.0)
100
100
  tins (1.26.0)
101
101
  sync
102
- twitter_cldr (6.6.0)
102
+ twitter_cldr (6.7.0)
103
103
  camertron-eprun
104
104
  cldr-plurals-runtime-rb (~> 1.1)
105
105
  tzinfo
@@ -44,6 +44,14 @@ module Kitchen
44
44
  pages('$.introduction').first
45
45
  end
46
46
 
47
+ # Returns true if the chapter has an introduction
48
+ #
49
+ # @return [Boolean]
50
+ #
51
+ def has_introduction?
52
+ @has_introduction ||= introduction_page.present?
53
+ end
54
+
47
55
  # Returns an enumerator for the glossaries
48
56
  #
49
57
  # @return [ElementEnumerator]
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeAnnotationClasses
6
+ def self.v1(chapter:)
7
+ V1.new.bake(
8
+ chapter: chapter)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeAnnotationClasses
4
+ class V1
5
+ def bake(chapter:)
6
+ chapter.search('p.annotation').each do |annotation|
7
+ annotation.wrap_children('span', class: 'os-text')
8
+ annotation.prepend(child:
9
+ <<~HTML
10
+ <div class="os-icons"></div>
11
+ HTML
12
+ )
13
+ end
14
+ annotation_icon_classes = %w[linguistic-icon
15
+ culture-icon
16
+ dreaming-icon
17
+ visual-icon
18
+ speech-icon
19
+ auditory-icon
20
+ kinesthetic-icon]
21
+ annotation_icon_classes.each do |annotation_icon_class|
22
+ chapter.search("p.#{annotation_icon_class}").each do |annotation_with_icon_class|
23
+ annotation_with_icon_class.search('div.os-icons').first.append(child:
24
+ <<~HTML
25
+ <span class = "#{annotation_icon_class}"></span>
26
+ HTML
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -10,7 +10,6 @@ module Kitchen::Directions::BakeChapterKeyConcepts
10
10
  uuid_key: "#{uuid_prefix}key-concepts",
11
11
  section_selector: 'section.key-concepts',
12
12
  append_to: append_to || chapter,
13
- include_intro_page: false,
14
13
  wrap_section: true, wrap_content: true
15
14
  ) do |section|
16
15
  Kitchen::Directions::RemoveSectionTitle.v1(section: section)
@@ -3,9 +3,7 @@
3
3
  module Kitchen::Directions::BakeChapterReferences
4
4
  class V1
5
5
  def bake(chapter:, metadata_source:, uuid_prefix: '.', klass: 'references')
6
- bake_page_references(page: chapter.introduction_page)
7
-
8
- chapter.non_introduction_pages.each do |page|
6
+ chapter.pages.each do |page|
9
7
  bake_page_references(page: page)
10
8
  end
11
9
 
@@ -18,7 +18,7 @@ module Kitchen
18
18
  def bake(chapter:, metadata_source:, uuid_prefix: '.', klass: 'summary')
19
19
  summaries = Clipboard.new
20
20
 
21
- chapter.non_introduction_pages.each do |page|
21
+ chapter.pages.each do |page|
22
22
  summary = page.summary
23
23
 
24
24
  next if summary.nil?
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module ChangeSubsectionTitleTag
6
+ def self.v1(section:)
7
+ section.search('section').each do |subsection|
8
+ subsection.first('h4').name = 'h5'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -54,6 +54,8 @@ module Kitchen
54
54
  next unless commentary.present?
55
55
 
56
56
  commentary_title = commentary.titles.first
57
+ next unless commentary_title.present?
58
+
57
59
  commentary_title.name = 'h4'
58
60
  commentary_title['data-type'] = 'commentary-title'
59
61
  commentary_title.wrap_children('span', class: 'os-title-label')
@@ -3,13 +3,15 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeFirstElements
6
- def self.v1(within:)
6
+ def self.v1(within:, first_inline_list: false)
7
7
  # add has-first-element class
8
8
  selectors = [
9
9
  'div.os-problem-container > div.os-table',
10
10
  'div.os-problem-container > span[data-type="media"]',
11
+ 'div.os-problem-container > div.os-figure',
11
12
  'div.os-solution-container > div.os-table',
12
- 'div.os-solution-container > span[data-type="media"]'
13
+ 'div.os-solution-container > span[data-type="media"]',
14
+ 'div.os-solution-container > div.os-figure'
13
15
  ]
14
16
  selectors.each do |selector|
15
17
  within.search("#{selector}:first-child").each do |problem|
@@ -18,9 +20,11 @@ module Kitchen
18
20
  end
19
21
  end
20
22
 
23
+ return unless first_inline_list
24
+
21
25
  # add first-inline-element class
22
26
  inline_selector = 'div.os-solution-container > ol[type="1"]:first-child,' \
23
- 'div.os-problem-container > ol[type="1"]:first-child'
27
+ 'div.os-problem-container > ol[type="1"]:first-child'
24
28
  within.search(inline_selector).each do |inline_list|
25
29
  inline_list.add_class('first-inline-list-element')
26
30
  inline_list.parent.add_class('has-first-inline-list-element')
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeFolio
6
+ def self.v1(book:)
7
+ book['data-pdf-folio-preface-message'] = I18n.t(:"folio.preface")
8
+ book['data-pdf-folio-access-message'] = I18n.t(:"folio.access_for_free")
9
+ end
10
+ end
11
+ end
12
+ end
@@ -8,7 +8,7 @@ module Kitchen::Directions::BakeFreeResponse
8
8
  @metadata_elements = metadata_source.children_to_keep.copy
9
9
 
10
10
  @free_response_clipboard = Kitchen::Clipboard.new
11
- chapter.non_introduction_pages.each do |page|
11
+ chapter.pages.each do |page|
12
12
  free_response_questions = page.free_response
13
13
  next if free_response_questions.none?
14
14
 
@@ -20,8 +20,7 @@ module Kitchen
20
20
  container_key: 'further-research',
21
21
  uuid_key: "#{uuid_prefix}further-research",
22
22
  section_selector: 'section.further-research',
23
- append_to: nil,
24
- include_intro_page: false
23
+ append_to: nil
25
24
  ) do |further_research|
26
25
  RemoveSectionTitle.v1(section: further_research)
27
26
  title = EocSectionTitleLinkSnippet.v1(page: further_research.ancestor(:page))
@@ -5,24 +5,65 @@ module Kitchen
5
5
  # Bake directions for table body
6
6
  #
7
7
  module BakeTableBody
8
- def self.v1(table:, number:)
9
- table.remove_attribute('summary')
10
- table.wrap(%(<div class="os-table">))
11
-
12
- table_label = "#{I18n.t(:table_label)} #{number}"
13
- table.pantry(name: :link_text).store table_label, label: table.id if table.id
14
-
15
- if table.top_titled?
16
- table.parent.add_class('os-top-titled-container')
17
- table.prepend(sibling:
18
- <<~HTML
19
- <div class="os-table-title">#{table.title}</div>
20
- HTML
21
- )
22
- table.title_row.trash
8
+ class V1
9
+ renderable
10
+ class CustomBody
11
+ attr_reader :table
12
+ attr_reader :klass
13
+ attr_reader :fake_title_class
14
+ attr_reader :fake_title
15
+ attr_reader :to_trash
16
+
17
+ def initialize(table:, klass:, fake_title_class: nil, fake_title: nil, to_trash: nil)
18
+ @table = table
19
+ @klass = klass
20
+ @fake_title_class = fake_title_class
21
+ @fake_title = fake_title
22
+ @to_trash = to_trash
23
+ end
24
+
25
+ def modify_body(has_fake_title: false)
26
+ @table.parent.add_class("os-#{@klass}-container")
27
+
28
+ return unless has_fake_title
29
+
30
+ @table.prepend(sibling:
31
+ <<~HTML
32
+ <div class="#{@fake_title_class}">#{@fake_title}</div>
33
+ HTML
34
+ )
35
+ @to_trash.trash
36
+ end
23
37
  end
24
38
 
25
- table.parent.add_class('os-column-header-container') if table.column_header?
39
+ def bake(table:, number:)
40
+ table.remove_attribute('summary')
41
+ table.wrap(%(<div class="os-table">))
42
+
43
+ table_label = "#{I18n.t(:table_label)} #{number}"
44
+ table.pantry(name: :link_text).store table_label, label: table.id if table.id
45
+
46
+ if table.top_titled?
47
+ custom_table = CustomBody.new(table: table,
48
+ klass: 'top-titled',
49
+ fake_title_class: 'os-table-title',
50
+ fake_title: table.title,
51
+ to_trash: table.title_row)
52
+
53
+ custom_table.modify_body(has_fake_title: true)
54
+ elsif table.top_captioned?
55
+ custom_table = CustomBody.new(table: table,
56
+ klass: 'top-captioned',
57
+ fake_title_class: 'os-top-caption',
58
+ fake_title: table.caption_title,
59
+ to_trash: table.top_caption)
60
+
61
+ custom_table.modify_body(has_fake_title: true)
62
+ elsif table.column_header?
63
+ custom_table = CustomBody.new(table: table, klass: 'column-header')
64
+ custom_table.modify_body(has_fake_title: false)
65
+ end
66
+ end
26
67
  end
27
68
  end
28
69
  end
@@ -4,7 +4,7 @@ module Kitchen::Directions::BakeNumberedTable
4
4
  class V1
5
5
 
6
6
  def bake(table:, number:, always_caption: false)
7
- Kitchen::Directions::BakeTableBody.v1(table: table, number: number)
7
+ Kitchen::Directions::BakeTableBody::V1.new.bake(table: table, number: number)
8
8
 
9
9
  # TODO: extra spaces added here to match legacy implementation, but probably not meaningful?
10
10
  new_caption = ''
@@ -6,10 +6,10 @@ module Kitchen::Directions::BakeNumberedTable
6
6
  class V2
7
7
 
8
8
  def bake(table:, number:)
9
- Kitchen::Directions::BakeTableBody.v1(table: table, number: number)
9
+ Kitchen::Directions::BakeTableBody::V1.new.bake(table: table, number: number)
10
10
 
11
11
  caption = ''
12
- if table&.caption&.first("span[data-type='title']")
12
+ if table&.caption&.first("span[data-type='title']") && !table.top_captioned?
13
13
  caption_el = table.caption
14
14
  caption_el.add_class('os-caption')
15
15
  caption_el.name = 'span'
@@ -3,8 +3,10 @@
3
3
  module Kitchen::Directions::BakeUnitPageTitle
4
4
  class V1
5
5
  def bake(book:)
6
- book.units.pages.each do |page|
7
- compose_unit_page_title(page: page)
6
+ book.units.each do |unit|
7
+ unit.element_children.only(Kitchen::PageElement).each do |page|
8
+ compose_unit_page_title(page: page)
9
+ end
8
10
  end
9
11
  end
10
12
 
@@ -3,30 +3,41 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module EocSectionTitleLinkSnippet
6
- def self.v1(page:)
7
- chapter = page.ancestor(:chapter)
8
- <<~HTML
9
- <a href="##{page.title.id}">
10
- <h3 data-type="document-title" id="#{page.title.copied_id}">
11
- <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
6
+ def self.v1(page:, title_tag: 'h3', wrapper: 'link')
7
+ if page.is_introduction?
8
+ os_number = ''
9
+ else
10
+ chapter = page.ancestor(:chapter)
11
+ os_number =
12
+ <<~HTML
13
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in_chapter_without_intro_page}</span>
12
14
  <span class="os-divider"> </span>
13
- <span class="os-text" data-type="" itemprop="">#{page.title_text}</span>
14
- </h3>
15
- </a>
16
- HTML
17
- end
15
+ HTML
16
+ end
18
17
 
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>
18
+ title_snippet = <<~HTML
19
+ <#{title_tag} data-type="document-title" id="#{page.title.copied_id}">
20
+ #{os_number}
21
+ <span class="os-text" data-type="" itemprop="">#{page.title_text}</span>
22
+ </#{title_tag}>
29
23
  HTML
24
+
25
+ case wrapper
26
+ when 'link'
27
+ <<~HTML
28
+ <a href="##{page.title.id}">
29
+ #{title_snippet}
30
+ </a>
31
+ HTML
32
+ when 'div'
33
+ <<~HTML
34
+ <div>
35
+ #{title_snippet}
36
+ </div>
37
+ HTML
38
+ else
39
+ title_snippet
40
+ end
30
41
  end
31
42
  end
32
43
  end
@@ -14,11 +14,10 @@ module Kitchen
14
14
  # @param uuid_key [String] the uuid key for the wrapper class, e.g. `'.summary'`
15
15
  # @param section_selector [String] the selector for the section to be moved, e.g. `'section.summary'`
16
16
  # @param append_to [ElementBase] the element to be appended. Defaults to the value of `chapter` param if none given.
17
- # @param include_intro_page [Boolean] control the introduction page for the chapter should be searched for a section to move, default is true
18
17
  # @return [ElementBase] the append_to element with container appended
19
18
  #
20
19
  def self.v1(chapter:, metadata_source:, container_key:, uuid_key:,
21
- section_selector:, append_to: nil, include_intro_page: true,
20
+ section_selector:, append_to: nil,
22
21
  wrap_section: false, wrap_content: false)
23
22
  V1.new.bake(
24
23
  chapter: chapter,
@@ -27,7 +26,6 @@ module Kitchen
27
26
  uuid_key: uuid_key,
28
27
  section_selector: section_selector,
29
28
  append_to: append_to || chapter,
30
- include_intro_page: include_intro_page,
31
29
  wrap_section: wrap_section,
32
30
  wrap_content: wrap_content
33
31
  ) do |section|
@@ -5,10 +5,10 @@
5
5
  module Kitchen::Directions::MoveCustomSectionToEocContainer
6
6
  class V1
7
7
  def bake(chapter:, metadata_source:, container_key:, uuid_key:,
8
- section_selector:, append_to:, include_intro_page:, wrap_section:, wrap_content:,
8
+ section_selector:, append_to:, wrap_section:, wrap_content:,
9
9
  &block)
10
10
  section_clipboard = Kitchen::Clipboard.new
11
- pages = include_intro_page ? chapter.pages : chapter.non_introduction_pages
11
+ pages = chapter.pages
12
12
  sections = pages.search(section_selector)
13
13
  sections.each(&block)
14
14
  if wrap_section
@@ -9,8 +9,7 @@ module Kitchen::Directions::MoveExercisesToEOC
9
9
  container_key: klass,
10
10
  uuid_key: "#{uuid_prefix}#{klass}",
11
11
  section_selector: "section.#{klass}",
12
- append_to: append_to || chapter,
13
- include_intro_page: false
12
+ append_to: append_to || chapter
14
13
  ) do |exercise_section|
15
14
  Kitchen::Directions::RemoveSectionTitle.v1(section: exercise_section)
16
15
  end
@@ -12,7 +12,6 @@ module Kitchen::Directions::MoveExercisesToEOC
12
12
  uuid_key: "#{uuid_prefix}#{klass}",
13
13
  section_selector: "section.#{klass}",
14
14
  append_to: append_to || chapter,
15
- include_intro_page: false,
16
15
  wrap_section: true, wrap_content: true
17
16
  ) do |section|
18
17
  Kitchen::Directions::RemoveSectionTitle.v1(section: section)
@@ -11,8 +11,7 @@ module Kitchen::Directions::MoveExercisesToEOC
11
11
  container_key: klass,
12
12
  uuid_key: "#{uuid_prefix}#{klass}",
13
13
  section_selector: "section.#{klass}",
14
- append_to: append_to || chapter,
15
- include_intro_page: false
14
+ append_to: append_to || chapter
16
15
  ) do |exercise_section|
17
16
  Kitchen::Directions::RemoveSectionTitle.v1(section: exercise_section)
18
17
  title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::MoveSolutionsFromExerciseSection
4
+ def self.v1(chapter:, append_to:, section_class:, title_number: nil)
5
+ V1.new.bake(chapter: chapter, append_to: append_to, section_class: section_class,
6
+ title_number: title_number)
7
+ end
8
+
9
+ class V1
10
+ def bake(chapter:, append_to:, section_class:, title_number:)
11
+ solutions_clipboard = Kitchen::Clipboard.new
12
+ chapter.search("section.#{section_class}").exercises.each do |exercise|
13
+ solution = exercise.solution
14
+ next unless solution
15
+
16
+ solution.cut(to: solutions_clipboard)
17
+ end
18
+
19
+ return if solutions_clipboard.items.empty?
20
+
21
+ title_text = \
22
+ if title_number
23
+ I18n.t(:"eoc.#{section_class}", number: title_number)
24
+ else
25
+ I18n.t(:"eoc.#{section_class}")
26
+ end
27
+ title = <<~HTML
28
+ <h3 data-type="title">
29
+ <span class="os-title-label">#{title_text}</span>
30
+ </h3>
31
+ HTML
32
+
33
+ append_to.append(child:
34
+ Kitchen::Directions::SolutionAreaSnippet.v1(
35
+ title: title, solutions_clipboard: solutions_clipboard
36
+ )
37
+ )
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::MoveSolutionsFromNumberedNote
4
+ def self.v1(chapter:, append_to:, note_class:)
5
+ V1.new.bake(chapter: chapter, append_to: append_to, note_class: note_class)
6
+ end
7
+
8
+ class V1
9
+ def bake(chapter:, append_to:, note_class:)
10
+ solutions_clipboard = Kitchen::Clipboard.new
11
+ chapter.notes("$.#{note_class}").exercises.each do |exercise|
12
+ solution = exercise.solution
13
+ next unless solution
14
+
15
+ solution.cut(to: solutions_clipboard)
16
+ end
17
+
18
+ return if solutions_clipboard.items.empty?
19
+
20
+ title = <<~HTML
21
+ <h3 data-type="title">
22
+ <span class="os-title-label">#{I18n.t(:"notes.#{note_class}")}</span>
23
+ </h3>
24
+ HTML
25
+
26
+ append_to.append(child:
27
+ Kitchen::Directions::SolutionAreaSnippet.v1(
28
+ title: title, solutions_clipboard: solutions_clipboard
29
+ )
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::SolutionAreaSnippet
4
+ def self.v1(title:, solutions_clipboard:)
5
+ <<~HTML
6
+ <div class="os-solution-area">
7
+ #{title}
8
+ #{solutions_clipboard.paste}
9
+ </div>
10
+ HTML
11
+ end
12
+ end
@@ -25,7 +25,7 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
25
25
  protected
26
26
 
27
27
  def append_solution_area(title, clipboard, append_to)
28
- append_to.add_child(
28
+ append_to.append(child:
29
29
  <<~HTML
30
30
  <div class="os-solution-area">
31
31
  <h3 data-type="title">
@@ -4,36 +4,19 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
4
4
  module Strategies
5
5
  class ContemporaryMath
6
6
  def bake(chapter:, append_to:)
7
- solutions_clipboard = Kitchen::Clipboard.new
7
+ # Hacky numbering fix
8
8
  chapter.notes('$.your-turn').exercises.each do |exercise|
9
9
  solution = exercise.solution
10
10
  next unless solution
11
11
 
12
- # Hacky numbering fix
13
12
  number = exercise.ancestor(:note).count_in(:chapter)
14
13
  solution.first('a.os-number').inner_html = number.to_s
15
14
  solution.first('span.os-divider').inner_html = '. '
16
- solution.cut(to: solutions_clipboard)
17
15
  end
18
- title = <<~HTML
19
- <h3 data-type="title">
20
- <span class="os-title-label">#{I18n.t(:'notes.your-turn')}</span>
21
- </h3>
22
- HTML
23
- append_solution_area(title: title, solutions: solutions_clipboard,
24
- append_to: append_to)
25
- end
26
-
27
- def append_solution_area(title:, solutions:, append_to:)
28
- append_to = append_to.add_child(
29
- <<~HTML
30
- <div class="os-solution-area">
31
- #{title}
32
- </div>
33
- HTML
34
- ).first
35
16
 
36
- append_to.add_child(solutions.paste)
17
+ Kitchen::Directions::MoveSolutionsFromNumberedNote.v1(
18
+ chapter: chapter, append_to: append_to, note_class: 'your-turn'
19
+ )
37
20
  end
38
21
  end
39
22
  end
@@ -12,7 +12,7 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
12
12
  def bake_section(chapter:, append_to:)
13
13
  @selectors.each do |selector|
14
14
  chapter.search("#{selector} div[data-type='solution']").each do |solution|
15
- append_to.add_child(solution.cut.to_s)
15
+ append_to.append(child: solution.cut.to_s)
16
16
  end
17
17
  end
18
18
  end
@@ -9,40 +9,25 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
9
9
  # Bake section exercises
10
10
  chapter.non_introduction_pages.each do |page|
11
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)
12
+ Kitchen::Directions::MoveSolutionsFromExerciseSection.v1(
13
+ chapter: page, append_to: append_to, section_class: 'section-exercises',
14
+ title_number: number
15
+ )
14
16
  end
15
17
 
16
18
  # Bake other types of exercises
17
19
  classes = %w[review-exercises practice-test]
18
20
  classes.each do |klass|
19
- bake_section(chapter: chapter, append_to: append_to, klass: klass)
21
+ Kitchen::Directions::MoveSolutionsFromExerciseSection.v1(
22
+ chapter: chapter, append_to: append_to, section_class: klass
23
+ )
20
24
  end
21
25
  end
22
26
 
23
27
  protected
24
28
 
25
- def bake_section(chapter:, append_to:, klass:, number: nil)
26
- section_solutions_set = Kitchen::Clipboard.new
27
- chapter.search("section.#{klass}").each do |section|
28
- section.search('div[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
29
  def try_note_solutions(chapter:, append_to:)
45
- append_to.add_child(
30
+ append_to.append(child:
46
31
  <<~HTML
47
32
  <div class="os-module-reset-solution-area os-try-solution-area">
48
33
  <h3 data-type="title">
@@ -51,7 +36,7 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
51
36
  </div>
52
37
  HTML
53
38
  )
54
- chapter.non_introduction_pages.each do |page|
39
+ chapter.pages.each do |page|
55
40
  solutions = Kitchen::Clipboard.new
56
41
  page.notes('$.try').each do |note|
57
42
  note.exercises.each do |exercise|
@@ -61,24 +46,18 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
61
46
  end
62
47
  next if solutions.items.empty?
63
48
 
64
- title_snippet = Kitchen::Directions::EocSectionTitleLinkSnippet.v2(page: page)
49
+ title_snippet = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(
50
+ page: page,
51
+ wrapper: 'div'
52
+ )
65
53
 
66
- append_solution_area(title: title_snippet, solutions: solutions,
67
- append_to: append_to.search('div.os-try-solution-area').first)
54
+ append_to.first('div.os-try-solution-area').append(child:
55
+ Kitchen::Directions::SolutionAreaSnippet.v1(
56
+ title: title_snippet, solutions_clipboard: solutions
57
+ )
58
+ )
68
59
  end
69
60
  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
61
  end
83
62
  end
84
63
  end
@@ -4,58 +4,16 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
4
4
  module Strategies
5
5
  class UPhysics
6
6
  def bake(chapter:, append_to:)
7
- bake_from_notes(chapter: chapter, append_to: append_to, klass: 'check-understanding')
7
+ Kitchen::Directions::MoveSolutionsFromNumberedNote.v1(
8
+ chapter: chapter, append_to: append_to, note_class: 'check-understanding'
9
+ )
8
10
 
9
11
  classes = %w[review-conceptual-questions review-problems review-additional-problems
10
12
  review-challenge]
11
13
  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('div[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
- note.exercises.each do |exercise|
36
- solution = exercise.solution
37
- solutions.push(solution.cut) if solution
38
- end
39
- end
40
- return if solutions.empty?
41
-
42
- title = I18n.t(:"notes.#{klass}")
43
- append_solution_area(title, solutions, append_to)
44
- end
45
-
46
- def append_solution_area(title, solutions, append_to)
47
- append_to = append_to.add_child(
48
- <<~HTML
49
- <div class="os-solution-area">
50
- <h3 data-type="title">
51
- <span class="os-title-label">#{title}</span>
52
- </h3>
53
- </div>
54
- HTML
55
- ).first
56
-
57
- solutions.each do |solution|
58
- append_to.add_child(solution.raw)
14
+ Kitchen::Directions::MoveSolutionsFromExerciseSection.v1(
15
+ chapter: chapter, append_to: append_to, section_class: klass
16
+ )
59
17
  end
60
18
  end
61
19
  end
@@ -23,10 +23,11 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
23
23
  end
24
24
 
25
25
  solutions_or_solution = solutions_plural ? 'solutions' : 'solution'
26
+ uuid_key = ".#{solutions_or_solution}#{chapter.count_in(:book)}"
26
27
  append_to.append(child:
27
28
  <<~HTML
28
29
  <div class="os-eob os-#{solutions_or_solution}-container" data-type="composite-page" \
29
- data-uuid-key=".#{solutions_or_solution}#{chapter.count_in(:book)}">
30
+ data-uuid-key="#{uuid_key}">
30
31
  <h2 data-type="document-title">
31
32
  <span class="os-text">#{I18n.t(:chapter)} #{chapter.count_in(:book)}</span>
32
33
  </h2>
@@ -37,7 +38,7 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
37
38
  </div>
38
39
  HTML
39
40
  )
40
- strategy.bake(chapter: chapter, append_to: append_to.last_element)
41
+ strategy.bake(chapter: chapter, append_to: append_to.first("[data-uuid-key='#{uuid_key}']"))
41
42
  end
42
43
  # rubocop:enable Metrics/ParameterLists
43
44
  end
@@ -722,10 +722,6 @@ module Kitchen
722
722
  end
723
723
  end
724
724
 
725
- def last_element
726
- node.last_element_child
727
- end
728
-
729
725
  # @!method pages
730
726
  # Returns a pages enumerator
731
727
  def_delegators :as_enumerator, :pages, :chapters, :terms, :figures, :notes, :tables, :examples,
@@ -58,7 +58,18 @@ module Kitchen
58
58
  # @return [Boolean]
59
59
  #
60
60
  def is_introduction?
61
- has_class?('introduction')
61
+ @is_introduction ||= has_class?('introduction')
62
+ end
63
+
64
+ # Returns replaces generic call to page.count_in(:chapter)
65
+ #
66
+ # @raise [StandardError] if called on an introduction page
67
+ # @return [Integer]
68
+ #
69
+ def count_in_chapter_without_intro_page
70
+ raise 'Introduction pages cannot be counted with this method' if is_introduction?
71
+
72
+ count_in(:chapter) - (ancestor(:chapter).has_introduction? ? 1 : 0)
62
73
  end
63
74
 
64
75
  # Returns true if this page is a preface
@@ -48,6 +48,31 @@ module Kitchen
48
48
  has_class?('top-titled')
49
49
  end
50
50
 
51
+ # Returns an element for the top caption, if present
52
+ #
53
+ # @return [Element, nil]
54
+ #
55
+ def top_caption
56
+ top_captioned? ? first('caption') : nil
57
+ end
58
+
59
+ # Returns the caption title nodes
60
+ #
61
+ # @return [Nokogiri::XML::NodeSet]
62
+ #
63
+ def caption_title
64
+ top_caption&.first('span[data-type="title"]')&.children
65
+ end
66
+
67
+ # Returns true if the table has a caption at the top
68
+ # that transforms to top title
69
+ #
70
+ # @return [Boolean]
71
+ #
72
+ def top_captioned?
73
+ has_class?('top-captioned')
74
+ end
75
+
51
76
  # Returns true if the table is unnumbered
52
77
  #
53
78
  # @return [Boolean]
@@ -3,5 +3,5 @@
3
3
  # A library for modifying the structure of OpenStax book XML.
4
4
  #
5
5
  module Kitchen
6
- VERSION = '10.0.0'
6
+ VERSION = '11.0.0'
7
7
  end
data/lib/locales/en.yml CHANGED
@@ -36,3 +36,6 @@ en:
36
36
  key-concepts: Key Concepts
37
37
  references: References
38
38
  solutions: Solutions
39
+ folio:
40
+ preface: Preface
41
+ access_for_free: Access for free at openstax.org
data/lib/locales/es.yml CHANGED
@@ -33,3 +33,6 @@ es:
33
33
  summary: Resumen
34
34
  further-research: Investigación Adicional
35
35
  references: Referencias
36
+ folio:
37
+ preface: Prefacio
38
+ access_for_free: Acceso gratis en openstax.org
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstax_kitchen
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.0.0
4
+ version: 11.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - JP Slavinsky
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-30 00:00:00.000000000 Z
11
+ date: 2021-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -243,6 +243,8 @@ files:
243
243
  - lib/kitchen/counter.rb
244
244
  - lib/kitchen/debug/print_recipe_error.rb
245
245
  - lib/kitchen/directions/.rubocop.yml
246
+ - lib/kitchen/directions/bake_annotation_classes/main.rb
247
+ - lib/kitchen/directions/bake_annotation_classes/v1.rb
246
248
  - lib/kitchen/directions/bake_appendix.rb
247
249
  - lib/kitchen/directions/bake_chapter_glossary/main.rb
248
250
  - lib/kitchen/directions/bake_chapter_glossary/v1.rb
@@ -263,11 +265,13 @@ files:
263
265
  - lib/kitchen/directions/bake_checkpoint.rb
264
266
  - lib/kitchen/directions/bake_composite_chapters.rb
265
267
  - lib/kitchen/directions/bake_composite_pages.rb
268
+ - lib/kitchen/directions/bake_eoc_section_content/change_subsection_title_tag.rb
266
269
  - lib/kitchen/directions/bake_eoc_section_content/remove_section_title.rb
267
270
  - lib/kitchen/directions/bake_equations.rb
268
271
  - lib/kitchen/directions/bake_example.rb
269
272
  - lib/kitchen/directions/bake_figure.rb
270
273
  - lib/kitchen/directions/bake_first_elements.rb
274
+ - lib/kitchen/directions/bake_folio.rb
271
275
  - lib/kitchen/directions/bake_footnotes/main.rb
272
276
  - lib/kitchen/directions/bake_footnotes/v1.rb
273
277
  - lib/kitchen/directions/bake_free_response/free_response.xhtml.erb
@@ -328,6 +332,9 @@ files:
328
332
  - lib/kitchen/directions/move_exercises_to_eoc/v2.rb
329
333
  - lib/kitchen/directions/move_exercises_to_eoc/v3.rb
330
334
  - lib/kitchen/directions/move_solutions_to_answer_key/main.rb
335
+ - lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_exercise_section.rb
336
+ - lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_numbered_note.rb
337
+ - lib/kitchen/directions/move_solutions_to_answer_key/solution_area_snippet.rb
331
338
  - lib/kitchen/directions/move_solutions_to_answer_key/strategies/calculus.rb
332
339
  - lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb
333
340
  - lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb