openstax_kitchen 9.2.0 → 10.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/kitchen/directions/bake_chapter_glossary/main.rb +3 -2
  5. data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +10 -1
  6. data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +12 -21
  7. data/lib/kitchen/directions/bake_chapter_solutions/main.rb +7 -2
  8. data/lib/kitchen/directions/bake_chapter_solutions/v1.rb +11 -9
  9. data/lib/kitchen/directions/bake_chapter_summary.rb +0 -1
  10. data/lib/kitchen/directions/bake_example.rb +3 -7
  11. data/lib/kitchen/directions/bake_first_elements.rb +6 -5
  12. data/lib/kitchen/directions/bake_further_research.rb +0 -1
  13. data/lib/kitchen/directions/bake_handbook/main.rb +11 -0
  14. data/lib/kitchen/directions/bake_handbook/v1.rb +74 -0
  15. data/lib/kitchen/directions/bake_lists_with_para.rb +17 -0
  16. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +19 -0
  17. data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +1 -1
  18. data/lib/kitchen/directions/bake_numbered_table/v1.rb +1 -1
  19. data/lib/kitchen/directions/bake_toc.rb +7 -0
  20. data/lib/kitchen/directions/bake_unit_page_title/main.rb +11 -0
  21. data/lib/kitchen/directions/bake_unit_page_title/v1.rb +21 -0
  22. data/lib/kitchen/directions/move_custom_section_to_eoc_container/main.rb +5 -2
  23. data/lib/kitchen/directions/move_custom_section_to_eoc_container/v1.rb +18 -2
  24. data/lib/kitchen/directions/move_exercises_to_eoc/v2.rb +12 -30
  25. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb +40 -0
  26. data/lib/kitchen/directions/move_solutions_to_answer_key/v1.rb +7 -1
  27. data/lib/kitchen/example_element.rb +9 -3
  28. data/lib/kitchen/exercise_element.rb +8 -0
  29. data/lib/kitchen/figure_element.rb +11 -0
  30. data/lib/kitchen/note_element.rb +8 -1
  31. data/lib/kitchen/page_element.rb +0 -8
  32. data/lib/kitchen/version.rb +1 -1
  33. data/lib/locales/en.yml +1 -0
  34. metadata +8 -4
  35. data/lib/kitchen/directions/bake_theorem/main.rb +0 -11
  36. data/lib/kitchen/directions/bake_theorem/v1.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddd15ebcb9ead1f1e6301bfc025a93bb3ca7e75d2e412eae3a63d3496574eea5
4
- data.tar.gz: 82af5aa1d8151438286f9e6cc21c052f5c7d1549b1966abaf3018f5578fb6f53
3
+ metadata.gz: 3a071ba6e289c222a7333f401c7d6bd25d6dba9527253b6c6ae123169d9b6425
4
+ data.tar.gz: 2debc535f61a289f6668019f1eeb5cd639efaf8d49172d668f8b602e02e91b07
5
5
  SHA512:
6
- metadata.gz: 268bf8bcf65bc1deb38d20e433b503e28eefc0048a5174bb7ea378354354f7c671e88b72378d03ad03ef077f2d15e5870c691bbdec358664e2f5c2c9344a9f33
7
- data.tar.gz: ef6c551bb52f90e7bf3301b38879cf2262a62dcc4b91b87c02c4ec944e30f71542dac6b4b3b65763e027737a13fd7b7a77ca86b57366025109b4539eb989f9f4
6
+ metadata.gz: 6bfeae3a664c95c17249ab32a8bba863091fb1e23f501273fd57d9752688c29ba9877b5a6404393dc88ae993f16af3f89fa768e3984cf81233908ab238b0350a
7
+ data.tar.gz: '086fa06f8f7eb33f3908c15ba0172a02a1738c943ba87b25245f63626cda51e5163edbece95cdce2ce1907d5815aefd179db7fb7e3a4fe2a7165c623c5120ede'
data/CHANGELOG.md CHANGED
@@ -6,6 +6,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [10.0.0] - 2021-07-30
10
+
11
+ * Add support for baking multipart questions to `BakeNumberedExercise` (minor)
12
+ * Add `has_para` option to `BakeChapterGlossary` for books from Adaptarr (minor)
13
+ * Create `BakeListsWithPara` to remove paragraphs from lists in books created by Adaptarr (minor)
14
+ * Create `Strategy::ContemporaryMath` (minor)
15
+ * Stop `BakeTableBody` from blowing up when table doesn't have an ID (patch)
16
+ * Refactor `MoveExercisesToEOC::V2` & `BakeChapterKeyConcepts` to use `MoveCustomSectionToEocContainer` (minor)
17
+ * Add wrapper support for `MoveCustomSectionToEocContainer` (minor)
18
+ * Create `BakeHandbook` direction (minor)
19
+ * Add `ExampleElement#titles_to_rename` & refactor `BakeExample` (patch)
20
+ * Create `BakeUnitPageTitle` (minor)
21
+ * Fix `BakeExample` to skip baked exercises (patch)
22
+ * Add `FigureElement#figure_to_bake?` (minor)
23
+ * Remove `itemprop` attribute from `BakeChapterSummary` and `BakeFurtherResearch` (major)
24
+ * Fix `NoteElement#title` to exclude nested element titles (patch)
25
+ * Remove `BakeTheorem` (minor)
26
+ * Allow `BakeChapterSolutions` to bake solutions from multiple sections (minor)
27
+ * Add `.os-problem-container` to `BakeFirstElement` selectors (minor)
28
+ * Tweak `BakeExample` to not touch unbaked titles in captions (minor/patch)
29
+ * Tweak `BakeNumberedTables.v1` to cut extra white space (minor)
30
+
9
31
  ## [9.2.0] - 2021-07-19
10
32
 
11
33
  * Update `BakeFirstElements` to also add the `.has-first-inline-list` class (minor)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openstax_kitchen (9.2.0)
4
+ openstax_kitchen (10.0.0)
5
5
  activesupport
6
6
  i18n
7
7
  nokogiri
@@ -5,12 +5,13 @@ module Kitchen
5
5
  # Bake directons for eoc glossary
6
6
  #
7
7
  module BakeChapterGlossary
8
- def self.v1(chapter:, metadata_source:, append_to: nil, uuid_prefix: nil)
8
+ def self.v1(chapter:, metadata_source:, append_to: nil, uuid_prefix: nil, has_para: false)
9
9
  V1.new.bake(
10
10
  chapter: chapter,
11
11
  metadata_source: metadata_source,
12
12
  append_to: append_to,
13
- uuid_prefix: uuid_prefix
13
+ uuid_prefix: uuid_prefix,
14
+ has_para: has_para
14
15
  )
15
16
  end
16
17
  end
@@ -21,9 +21,18 @@ module Kitchen::Directions::BakeChapterGlossary
21
21
  attr_reader :sortable
22
22
  end
23
23
 
24
- def bake(chapter:, metadata_source:, append_to: nil, uuid_prefix: '')
24
+ def bake(chapter:, metadata_source:, append_to: nil, uuid_prefix: '', has_para: false)
25
25
  @glossary = []
26
26
 
27
+ # Use for books created by Adaptarr, where dd contains paragraphs
28
+ # More info: https://github.com/openstax/kitchen/issues/284
29
+ if has_para
30
+ chapter.glossaries.search('dd').each do |description|
31
+ description_content = description.first('p').text
32
+ description.replace_children with: description_content
33
+ end
34
+ end
35
+
27
36
  chapter.glossaries.search('dl').each do |definition_element|
28
37
  @glossary.push(Definition.new(definition_element.cut))
29
38
  end
@@ -3,29 +3,20 @@
3
3
  module Kitchen::Directions::BakeChapterKeyConcepts
4
4
  class V1
5
5
  def bake(chapter:, metadata_source:, append_to:, uuid_prefix:)
6
- key_concepts_clipboard = Kitchen::Clipboard.new
7
- chapter.non_introduction_pages.each do |page|
8
- key_concepts = page.key_concepts
9
- next if key_concepts.none?
10
-
11
- title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
12
- key_concepts.each do |key_concept|
13
- Kitchen::Directions::RemoveSectionTitle.v1(section: key_concept)
14
- key_concept.prepend(child: title)
15
- key_concept.wrap("<div class='os-section-area'>")
16
- page.search('div.os-section-area').first.cut(to: key_concepts_clipboard)
17
- end
18
- end
19
-
20
- content = "<div class=\"os-key-concepts\"> #{key_concepts_clipboard.paste} </div>"
21
-
22
- Kitchen::Directions::EocCompositePageContainer.v1(
6
+ Kitchen::Directions::MoveCustomSectionToEocContainer.v1(
7
+ chapter: chapter,
8
+ metadata_source: metadata_source,
23
9
  container_key: 'key-concepts',
24
10
  uuid_key: "#{uuid_prefix}key-concepts",
25
- metadata_source: metadata_source,
26
- content: content,
27
- append_to: append_to || chapter
28
- )
11
+ section_selector: 'section.key-concepts',
12
+ append_to: append_to || chapter,
13
+ include_intro_page: false,
14
+ wrap_section: true, wrap_content: true
15
+ ) do |section|
16
+ Kitchen::Directions::RemoveSectionTitle.v1(section: section)
17
+ title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: section.ancestor(:page))
18
+ section.prepend(child: title)
19
+ end
29
20
  end
30
21
  end
31
22
  end
@@ -3,8 +3,13 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeChapterSolutions
6
- def self.v1(chapter:, metadata_source:, uuid_prefix: '')
7
- V1.new.bake(chapter: chapter, metadata_source: metadata_source, uuid_prefix: uuid_prefix)
6
+ def self.v1(chapter:, metadata_source:, uuid_prefix: '', classes: %w[free-response])
7
+ V1.new.bake(
8
+ chapter: chapter,
9
+ metadata_source: metadata_source,
10
+ uuid_prefix: uuid_prefix,
11
+ classes: classes
12
+ )
8
13
  end
9
14
  end
10
15
  end
@@ -2,20 +2,22 @@
2
2
 
3
3
  module Kitchen::Directions::BakeChapterSolutions
4
4
  class V1
5
- def bake(chapter:, metadata_source:, uuid_prefix: '')
5
+ def bake(chapter:, metadata_source:, uuid_prefix: '', classes: %w[free-response])
6
6
  solutions_clipboard = Kitchen::Clipboard.new
7
7
 
8
- chapter.search('section.free-response').each do |free_response_question|
9
- exercises = free_response_question.exercises
10
- # must run AFTER .free-response notes are baked
8
+ classes.each do |klass|
9
+ chapter.search("section.#{klass}").each do |question|
10
+ exercises = question.exercises
11
+ # must run AFTER the other sections are baked
11
12
 
12
- next if exercises.none?
13
+ next if exercises.none?
13
14
 
14
- exercises.each do |exercise|
15
- solution = exercise.solution
16
- next unless solution.present?
15
+ exercises.each do |exercise|
16
+ solution = exercise.solution
17
+ next unless solution.present?
17
18
 
18
- solution.cut(to: solutions_clipboard)
19
+ solution.cut(to: solutions_clipboard)
20
+ end
19
21
  end
20
22
  end
21
23
 
@@ -26,7 +26,6 @@ module Kitchen
26
26
  summary.first("[data-type='title']")&.trash # get rid of old title if exists
27
27
  title = EocSectionTitleLinkSnippet.v1(page: page)
28
28
  summary.prepend(child: title)
29
- summary.first('h3')[:itemprop] = 'name'
30
29
  summary.cut(to: summaries)
31
30
  end
32
31
 
@@ -20,18 +20,14 @@ module Kitchen
20
20
  .pantry(name: :link_text)
21
21
  .store("#{I18n.t(:example_label)} #{number}", label: example.id)
22
22
 
23
- example.titles.each do |title|
24
- if title.parent.has_class?('os-caption-container') || \
25
- title.parent.has_class?('os-caption')
26
- next
27
- end
28
-
23
+ example.titles_to_rename.each do |title|
29
24
  title.name = 'h4'
30
25
  end
31
26
 
32
27
  example.exercises.each do |exercise|
28
+ next if exercise.baked?
29
+
33
30
  if (problem = exercise.problem)
34
- problem.titles.each { |title| title.name = 'h4' }
35
31
  problem.wrap_children(class: 'os-problem-container')
36
32
  end
37
33
 
@@ -19,11 +19,12 @@ module Kitchen
19
19
  end
20
20
 
21
21
  # add first-inline-element class
22
- inline_list = within&.first('div.os-solution-container > ol[type="1"]:first-child')
23
- return unless inline_list
24
-
25
- inline_list.add_class('first-inline-list-element')
26
- inline_list.parent.add_class('has-first-inline-list-element')
22
+ inline_selector = 'div.os-solution-container > ol[type="1"]:first-child,' \
23
+ 'div.os-problem-container > ol[type="1"]:first-child'
24
+ within.search(inline_selector).each do |inline_list|
25
+ inline_list.add_class('first-inline-list-element')
26
+ inline_list.parent.add_class('has-first-inline-list-element')
27
+ end
27
28
  end
28
29
  end
29
30
  end
@@ -26,7 +26,6 @@ module Kitchen
26
26
  RemoveSectionTitle.v1(section: further_research)
27
27
  title = EocSectionTitleLinkSnippet.v1(page: further_research.ancestor(:page))
28
28
  further_research.prepend(child: title)
29
- further_research.first('h3')[:itemprop] = 'name'
30
29
  end
31
30
  end
32
31
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeHandbook
6
+ def self.v1(book:, title_element: 'h1')
7
+ V1.new.bake(book: book, title_element: title_element)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeHandbook
4
+ class V1
5
+ def bake(book:, title_element:)
6
+ book.pages('$.handbook').each do |page|
7
+ page.titles.each do |title|
8
+ title.replace_children(with:
9
+ <<~HTML
10
+ <span data-type="" itemprop="" class="os-text">#{title.text}</span>
11
+ HTML
12
+ )
13
+ title.name = title_element
14
+ end
15
+
16
+ # Create Outline Title
17
+ outline_html = <<~HTML
18
+ <div class="os-handbook-outline">
19
+ <h3 class="os-title">#{I18n.t(:handbook_outline_title)}</h3>
20
+ </div>
21
+ HTML
22
+ page.title.append(sibling: outline_html)
23
+
24
+ bake_first_section_title_and_objectives(page: page)
25
+ fix_nested_section_headers(page: page)
26
+ end
27
+ end
28
+
29
+ # Bake Handbook First Section Title
30
+ def bake_first_section_title_and_objectives(page:)
31
+ outline_items_html = []
32
+ page.search('> section').each do |section|
33
+ first_section_title = section.titles.first
34
+ first_section_title.replace_children(with:
35
+ <<~HTML
36
+ <span class="os-part-text">H</span>
37
+ <span class="os-number">#{section.count_in(:page)}</span>
38
+ <span class="os-divider">. </span>
39
+ <span class="os-text">#{first_section_title.text}</span>
40
+ HTML
41
+ )
42
+ first_section_title.name = 'h2'
43
+
44
+ outline_item_html = <<~HTML
45
+ <div class="os-handbook-objective">
46
+ <a class="os-handbook-objective" href="##{first_section_title[:id]}">
47
+ #{first_section_title.children}
48
+ </a>
49
+ </div>
50
+ HTML
51
+ outline_items_html.push(outline_item_html)
52
+ end
53
+ page.search('.os-handbook-outline').first.append(child:
54
+ <<~HTML
55
+ #{outline_items_html.join}
56
+ HTML
57
+ )
58
+ end
59
+
60
+ def fix_nested_section_headers(page:)
61
+ page.search('section').each do |section|
62
+ section_data_depth = section[:'data-depth']
63
+ case section_data_depth
64
+ when '2'
65
+ section.titles.first.name = 'h3'
66
+ when '3'
67
+ section.titles.first.name = 'h4'
68
+ when '4'
69
+ section.titles.first.name = 'h5'
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ # Bakes lists with paragraphs
6
+ # Should be used for books created by Adaptarr to put list text directly to <li>
7
+ #
8
+ module BakeListsWithPara
9
+ def self.v1(book:)
10
+ book.search('li').each do |item|
11
+ item_content = item.first('p')&.text
12
+ item.replace_children with: item_content unless item_content.nil?
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -37,6 +37,25 @@ module Kitchen::Directions::BakeNumberedExercise
37
37
  <div class="os-problem-container">#{problem.children}</div>
38
38
  HTML
39
39
  )
40
+
41
+ # Bake multipart questions
42
+ multipart_questions = problem.search('div.question-stem')
43
+ return unless multipart_questions.count > 1
44
+
45
+ multipart_clipboard = Kitchen::Clipboard.new
46
+ multipart_questions.each do |question|
47
+ question.wrap('<li>')
48
+ question = question.parent
49
+ question.cut(to: multipart_clipboard)
50
+ end
51
+
52
+ problem.first('div.question-stimulus, div.exercise-stimulus').append(sibling:
53
+ <<~HTML
54
+ <ol type="a">
55
+ #{multipart_clipboard.paste}
56
+ </ol>
57
+ HTML
58
+ )
40
59
  end
41
60
 
42
61
  def bake_solution(exercise:, number:, divider: '. ')
@@ -10,7 +10,7 @@ module Kitchen
10
10
  table.wrap(%(<div class="os-table">))
11
11
 
12
12
  table_label = "#{I18n.t(:table_label)} #{number}"
13
- table.pantry(name: :link_text).store table_label, label: table.id
13
+ table.pantry(name: :link_text).store table_label, label: table.id if table.id
14
14
 
15
15
  if table.top_titled?
16
16
  table.parent.add_class('os-top-titled-container')
@@ -16,7 +16,7 @@ module Kitchen::Directions::BakeNumberedTable
16
16
  HTML
17
17
  end
18
18
 
19
- if (caption = table.caption&.cut)
19
+ if (caption = table.caption&.cut) && !caption&.children&.to_s&.blank?
20
20
  new_caption = <<~HTML
21
21
  \n<span class="os-caption">#{caption.children}</span>
22
22
  HTML
@@ -28,6 +28,8 @@ module Kitchen
28
28
 
29
29
  def self.li_for_unit(unit)
30
30
  chapters = unit.element_children.only(ChapterElement)
31
+ pages = unit.element_children.only(PageElement)
32
+
31
33
  <<~HTML
32
34
  <li cnx-archive-uri="" cnx-archive-shortid="" class="os-toc-unit">
33
35
  <a href="#">
@@ -36,6 +38,7 @@ module Kitchen
36
38
  <span data-type itemprop class="os-text">#{unit.title_text}</span>
37
39
  </a>
38
40
  <ol class="os-unit">
41
+ #{pages.map { |page| li_for_page(page) }.join("\n")}
39
42
  #{chapters.map { |chapter| li_for_chapter(chapter) }.join("\n")}
40
43
  </ol>
41
44
  </li>
@@ -92,6 +95,10 @@ module Kitchen
92
95
  'os-toc-preface'
93
96
  elsif page.is_handbook?
94
97
  'os-toc-handbook'
98
+ elsif page.has_ancestor?(:unit) && !
99
+ page.has_ancestor?(:chapter) && !
100
+ page.has_ancestor?(:composite_chapter)
101
+ 'os-toc-unit-page'
95
102
  else
96
103
  raise "do not know what TOC class to use for page with classes #{page.classes}"
97
104
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeUnitPageTitle
6
+ def self.v1(book:)
7
+ V1.new.bake(book: book)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeUnitPageTitle
4
+ class V1
5
+ def bake(book:)
6
+ book.units.pages.each do |page|
7
+ compose_unit_page_title(page: page)
8
+ end
9
+ end
10
+
11
+ def compose_unit_page_title(page:)
12
+ title = page.title
13
+ title.name = 'h2'
14
+ title.replace_children(with:
15
+ <<~HTML
16
+ <span data-type="" itemprop="" class="os-text">#{title.text}</span>
17
+ HTML
18
+ )
19
+ end
20
+ end
21
+ end
@@ -18,7 +18,8 @@ module Kitchen
18
18
  # @return [ElementBase] the append_to element with container appended
19
19
  #
20
20
  def self.v1(chapter:, metadata_source:, container_key:, uuid_key:,
21
- section_selector:, append_to: nil, include_intro_page: true)
21
+ section_selector:, append_to: nil, include_intro_page: true,
22
+ wrap_section: false, wrap_content: false)
22
23
  V1.new.bake(
23
24
  chapter: chapter,
24
25
  metadata_source: metadata_source,
@@ -26,7 +27,9 @@ module Kitchen
26
27
  uuid_key: uuid_key,
27
28
  section_selector: section_selector,
28
29
  append_to: append_to || chapter,
29
- include_intro_page: include_intro_page
30
+ include_intro_page: include_intro_page,
31
+ wrap_section: wrap_section,
32
+ wrap_content: wrap_content
30
33
  ) do |section|
31
34
  yield section if block_given?
32
35
  end
@@ -5,20 +5,36 @@
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:, &block)
8
+ section_selector:, append_to:, include_intro_page:, wrap_section:, wrap_content:,
9
+ &block)
9
10
  section_clipboard = Kitchen::Clipboard.new
10
11
  pages = include_intro_page ? chapter.pages : chapter.non_introduction_pages
11
12
  sections = pages.search(section_selector)
12
13
  sections.each(&block)
14
+ if wrap_section
15
+ sections.each { |section| section.wrap('<div class="os-section-area">') }
16
+ sections = pages.search('div.os-section-area')
17
+ end
13
18
  sections.cut(to: section_clipboard)
14
19
 
15
20
  return if section_clipboard.none?
16
21
 
22
+ content = \
23
+ if wrap_content
24
+ <<~HTML
25
+ <div class="os-#{container_key}">
26
+ #{section_clipboard.paste}
27
+ </div>
28
+ HTML
29
+ else
30
+ section_clipboard.paste
31
+ end
32
+
17
33
  Kitchen::Directions::EocCompositePageContainer.v1(
18
34
  container_key: container_key,
19
35
  uuid_key: uuid_key,
20
36
  metadata_source: metadata_source,
21
- content: section_clipboard.paste,
37
+ content: content,
22
38
  append_to: append_to || chapter
23
39
  )
24
40
  end
@@ -5,38 +5,20 @@ module Kitchen::Directions::MoveExercisesToEOC
5
5
  # and some additional wrappers
6
6
  class V2
7
7
  def bake(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
8
- exercise_clipboard = Kitchen::Clipboard.new
9
-
10
- chapter.non_introduction_pages.each do |page|
11
- sections = page.search("section.#{klass}")
12
-
13
- sections.each do |exercise_section|
14
- Kitchen::Directions::RemoveSectionTitle.v1(section: exercise_section)
15
- # Get parent page title
16
- section_title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
17
- # Configure section title & wrappers
18
- exercise_section.prepend(child: section_title)
19
- exercise_section.wrap('<div class="os-section-area">')
20
- exercise_section = exercise_section.parent
21
- exercise_section.cut(to: exercise_clipboard)
22
- end
23
- end
24
-
25
- return if exercise_clipboard.none?
26
-
27
- content = <<~HTML
28
- <div class="os-#{klass}">
29
- #{exercise_clipboard.paste}
30
- </div>
31
- HTML
32
-
33
- Kitchen::Directions::EocCompositePageContainer.v1(
8
+ Kitchen::Directions::MoveCustomSectionToEocContainer.v1(
9
+ chapter: chapter,
10
+ metadata_source: metadata_source,
34
11
  container_key: klass,
35
12
  uuid_key: "#{uuid_prefix}#{klass}",
36
- metadata_source: metadata_source,
37
- content: content,
38
- append_to: append_to || chapter
39
- )
13
+ section_selector: "section.#{klass}",
14
+ append_to: append_to || chapter,
15
+ include_intro_page: false,
16
+ wrap_section: true, wrap_content: true
17
+ ) do |section|
18
+ Kitchen::Directions::RemoveSectionTitle.v1(section: section)
19
+ title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: section.ancestor(:page))
20
+ section.prepend(child: title)
21
+ end
40
22
  end
41
23
  end
42
24
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::MoveSolutionsToAnswerKey
4
+ module Strategies
5
+ class ContemporaryMath
6
+ def bake(chapter:, append_to:)
7
+ solutions_clipboard = Kitchen::Clipboard.new
8
+ chapter.notes('$.your-turn').exercises.each do |exercise|
9
+ solution = exercise.solution
10
+ next unless solution
11
+
12
+ # Hacky numbering fix
13
+ number = exercise.ancestor(:note).count_in(:chapter)
14
+ solution.first('a.os-number').inner_html = number.to_s
15
+ solution.first('span.os-divider').inner_html = '. '
16
+ solution.cut(to: solutions_clipboard)
17
+ 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
+
36
+ append_to.add_child(solutions.paste)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -2,11 +2,16 @@
2
2
 
3
3
  module Kitchen::Directions::MoveSolutionsToAnswerKey
4
4
  class V1
5
- def bake(chapter:, metadata_source:, strategy:, append_to:, strategy_options: {}, solutions_plural: true)
5
+ # rubocop:disable Metrics/ParameterLists
6
+ # This direction may need refactoring to simplify parameters
7
+ def bake(chapter:, metadata_source:, strategy:, append_to:, strategy_options: {},
8
+ solutions_plural: true)
6
9
  strategy =
7
10
  case strategy
8
11
  when :calculus
9
12
  Strategies::Calculus.new
13
+ when :contemporary_math
14
+ Strategies::ContemporaryMath.new
10
15
  when :uphysics
11
16
  Strategies::UPhysics.new
12
17
  when :precalculus
@@ -34,5 +39,6 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
34
39
  )
35
40
  strategy.bake(chapter: chapter, append_to: append_to.last_element)
36
41
  end
42
+ # rubocop:enable Metrics/ParameterLists
37
43
  end
38
44
  end
@@ -27,9 +27,15 @@ module Kitchen
27
27
  #
28
28
  # @return [ElementEnumerator]
29
29
  #
30
- def titles
31
- search("[data-type='title']")
30
+ def titles_to_rename
31
+ titles(except: \
32
+ lambda do |title|
33
+ title.parent.has_class?('os-caption-container') || \
34
+ title.parent.has_class?('os-caption') || \
35
+ title.parent.name == 'caption' || \
36
+ title.parent[:'data-type'] == 'note'
37
+ end
38
+ )
32
39
  end
33
-
34
40
  end
35
41
  end
@@ -38,5 +38,13 @@ module Kitchen
38
38
  def solution
39
39
  first("div[data-type='solution']")
40
40
  end
41
+
42
+ # Returns whether the exercise has been baked
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ def baked?
47
+ search('div.os-problem-container').any?
48
+ end
41
49
  end
42
50
  end
@@ -47,5 +47,16 @@ module Kitchen
47
47
  parent.name == 'figure'
48
48
  end
49
49
 
50
+ # Returns true unless the figure is a subfigure or has the 'unnumbered' class,
51
+ # unless the figure has both the 'unnumbered' and the 'splash' classes.
52
+ #
53
+ # @return [Boolean]
54
+ #
55
+ def figure_to_bake?
56
+ return false if subfigure? || (has_class?('unnumbered') && !has_class?('splash'))
57
+
58
+ true
59
+ end
60
+
50
61
  end
51
62
  end
@@ -29,7 +29,14 @@ module Kitchen
29
29
  #
30
30
  def title
31
31
  block_error_if(block_given?)
32
- first("[data-type='title']")
32
+ note_body = first('div.os-note-body')
33
+ first_child = note_body ? note_body.element_children[0] : element_children[0]
34
+
35
+ if first_child[:'data-type'] == 'title'
36
+ first_child
37
+ elsif first_child&.element_children&.[](0)&.[](:'data-type') == 'title'
38
+ first_child.element_children[0]
39
+ end
33
40
  end
34
41
 
35
42
  # Returns true if the note's title is autogenerated
@@ -103,14 +103,6 @@ module Kitchen
103
103
  first!('section.exercises')
104
104
  end
105
105
 
106
- # Returns the key concepts
107
- #
108
- # @return [Element]
109
- #
110
- def key_concepts
111
- search('section.key-concepts')
112
- end
113
-
114
106
  # Returns the free response questions
115
107
  #
116
108
  # @return [Element]
@@ -3,5 +3,5 @@
3
3
  # A library for modifying the structure of OpenStax book XML.
4
4
  #
5
5
  module Kitchen
6
- VERSION = '9.2.0'
6
+ VERSION = '10.0.0'
7
7
  end
data/lib/locales/en.yml CHANGED
@@ -27,6 +27,7 @@ en:
27
27
  review_exercises: Review Exercises
28
28
  section_exercises: ! 'Section %{number} Exercises'
29
29
  iframe_link_text: Click to view content
30
+ handbook_outline_title: Outline
30
31
  eoc:
31
32
  glossary: Key Terms
32
33
  key-equations: Key Equations
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: 9.2.0
4
+ version: 10.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-19 00:00:00.000000000 Z
11
+ date: 2021-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -274,11 +274,14 @@ files:
274
274
  - lib/kitchen/directions/bake_free_response/main.rb
275
275
  - lib/kitchen/directions/bake_free_response/v1.rb
276
276
  - lib/kitchen/directions/bake_further_research.rb
277
+ - lib/kitchen/directions/bake_handbook/main.rb
278
+ - lib/kitchen/directions/bake_handbook/v1.rb
277
279
  - lib/kitchen/directions/bake_index/main.rb
278
280
  - lib/kitchen/directions/bake_index/v1.rb
279
281
  - lib/kitchen/directions/bake_index/v1.xhtml.erb
280
282
  - lib/kitchen/directions/bake_inline_lists.rb
281
283
  - lib/kitchen/directions/bake_link_placeholders.rb
284
+ - lib/kitchen/directions/bake_lists_with_para.rb
282
285
  - lib/kitchen/directions/bake_math_in_paragraph.rb
283
286
  - lib/kitchen/directions/bake_non_introduction_pages.rb
284
287
  - lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb
@@ -303,9 +306,9 @@ files:
303
306
  - lib/kitchen/directions/bake_references/v2.rb
304
307
  - lib/kitchen/directions/bake_stepwise.rb
305
308
  - lib/kitchen/directions/bake_suggested_reading.rb
306
- - lib/kitchen/directions/bake_theorem/main.rb
307
- - lib/kitchen/directions/bake_theorem/v1.rb
308
309
  - lib/kitchen/directions/bake_toc.rb
310
+ - lib/kitchen/directions/bake_unit_page_title/main.rb
311
+ - lib/kitchen/directions/bake_unit_page_title/v1.rb
309
312
  - lib/kitchen/directions/bake_unit_title/main.rb
310
313
  - lib/kitchen/directions/bake_unit_title/v1.rb
311
314
  - lib/kitchen/directions/bake_unnumbered_tables.rb
@@ -326,6 +329,7 @@ files:
326
329
  - lib/kitchen/directions/move_exercises_to_eoc/v3.rb
327
330
  - lib/kitchen/directions/move_solutions_to_answer_key/main.rb
328
331
  - lib/kitchen/directions/move_solutions_to_answer_key/strategies/calculus.rb
332
+ - lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb
329
333
  - lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb
330
334
  - lib/kitchen/directions/move_solutions_to_answer_key/strategies/precalculus.rb
331
335
  - lib/kitchen/directions/move_solutions_to_answer_key/strategies/uphysics.rb
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kitchen
4
- module Directions
5
- module BakeTheorem
6
- def self.v1(theorem:, number:)
7
- V1.new.bake(theorem: theorem, number: number)
8
- end
9
- end
10
- end
11
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kitchen::Directions::BakeTheorem
4
- class V1
5
- def bake(theorem:, number:)
6
- theorem['use-subtitle'] = true
7
- new_subtitle = theorem.title.cut
8
-
9
- theorem.wrap_children(class: 'os-note-body')
10
- note_body = theorem.first('.os-note-body')
11
-
12
- note_body.prepend(sibling:
13
- <<~HTML
14
- <div class="os-title">
15
- <span class="os-title-label">#{I18n.t(:theorem)} </span>
16
- <span class="os-number">#{number}</span>
17
- <span class="os-divider"> </span>
18
- </div>
19
- HTML
20
- )
21
-
22
- new_subtitle.name = 'h4'
23
- new_subtitle.add_class('os-subtitle')
24
- new_subtitle.children.wrap('<span class="os-subtitle-label">')
25
- note_body.prepend(child: new_subtitle.paste)
26
- end
27
- end
28
- end