openstax_kitchen 6.0.0 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/changelog.yml +0 -3
  3. data/CHANGELOG.md +38 -4
  4. data/Gemfile.lock +2 -2
  5. data/docker/rubocop +6 -4
  6. data/lib/kitchen/chapter_element.rb +0 -8
  7. data/lib/kitchen/composite_page_element.rb +20 -3
  8. data/lib/kitchen/directions/.rubocop.yml +3 -0
  9. data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +30 -16
  10. data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +9 -13
  11. data/lib/kitchen/directions/bake_chapter_key_equations.rb +10 -17
  12. data/lib/kitchen/directions/bake_chapter_references/main.rb +1 -2
  13. data/lib/kitchen/directions/bake_chapter_references/v1.rb +33 -21
  14. data/lib/kitchen/directions/bake_chapter_solutions/v1.rb +8 -12
  15. data/lib/kitchen/directions/bake_chapter_summary.rb +10 -32
  16. data/lib/kitchen/directions/bake_eoc_section_content/remove_section_title.rb +11 -0
  17. data/lib/kitchen/directions/bake_example.rb +7 -1
  18. data/lib/kitchen/directions/bake_further_research.rb +13 -39
  19. data/lib/kitchen/directions/bake_inline_lists.rb +22 -0
  20. data/lib/kitchen/directions/bake_references/main.rb +7 -0
  21. data/lib/kitchen/directions/bake_references/v2.rb +35 -0
  22. data/lib/kitchen/directions/bake_toc.rb +3 -1
  23. data/lib/kitchen/directions/eoc_composite_page_container/main.rb +27 -0
  24. data/lib/kitchen/directions/eoc_composite_page_container/v1.rb +19 -0
  25. data/lib/kitchen/directions/move_custom_section_to_eoc_container/main.rb +37 -0
  26. data/lib/kitchen/directions/move_custom_section_to_eoc_container/v1.rb +27 -0
  27. data/lib/kitchen/directions/move_exercises_to_eoc/v1.rb +10 -27
  28. data/lib/kitchen/directions/move_exercises_to_eoc/v2.rb +11 -18
  29. data/lib/kitchen/directions/move_exercises_to_eoc/v3.rb +14 -38
  30. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/calculus.rb +5 -5
  31. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb +3 -3
  32. data/lib/kitchen/element_base.rb +2 -2
  33. data/lib/kitchen/example_element.rb +1 -1
  34. data/lib/kitchen/i18n_string.rb +16 -0
  35. data/lib/kitchen/patches/array.rb +15 -0
  36. data/lib/kitchen/templates/eoc_section_template.xhtml.erb +11 -0
  37. data/lib/kitchen/templates/eoc_section_template_old.xhtml.erb +11 -0
  38. data/lib/kitchen/version.rb +1 -1
  39. data/lib/locales/en.yml +7 -5
  40. data/lib/locales/es.yml +7 -5
  41. data/lib/locales/pl.yml +6 -3
  42. data/lib/openstax_kitchen.rb +1 -0
  43. metadata +13 -3
  44. data/lib/kitchen/templates/eoc_section_title_template.xhtml.erb +0 -10
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module RemoveSectionTitle
6
+ def self.v1(section:)
7
+ section.first('[data-type="title"]')&.trash
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,7 +3,7 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeExample
6
- def self.v1(example:, number:, title_tag:)
6
+ def self.v1(example:, number:, title_tag:, numbered_solutions: false)
7
7
  example.wrap_children(class: 'body')
8
8
 
9
9
  example.prepend(child:
@@ -36,10 +36,16 @@ module Kitchen
36
36
  end
37
37
 
38
38
  if (solution = exercise.solution)
39
+ solution_number = if numbered_solutions
40
+ "<span class=\"os-number\">#{exercise.count_in(:example)}</span>"
41
+ else
42
+ ''
43
+ end
39
44
  solution.replace_children(with:
40
45
  <<~HTML
41
46
  <h4 data-type="solution-title">
42
47
  <span class="os-title-label">#{I18n.t(:solution)} </span>
48
+ #{solution_number}
43
49
  </h4>
44
50
  <div class="os-solution-container">#{solution.children}</div>
45
51
  HTML
@@ -13,47 +13,21 @@ module Kitchen
13
13
  end
14
14
 
15
15
  class V1
16
- renderable
17
16
  def bake(chapter:, metadata_source:, uuid_prefix: '.')
18
- @metadata = metadata_source.children_to_keep.copy
19
- @klass = 'further-research'
20
- @title = I18n.t(:eoc_further_research_title)
21
- @uuid_prefix = uuid_prefix
22
-
23
- further_researches = Clipboard.new
24
-
25
- chapter.non_introduction_pages.each do |page|
26
- further_research = page.first('.further-research')
27
- next unless further_research.present?
28
-
29
- further_research.first("[data-type='title']")&.trash # get rid of old title if exists
30
- further_research_title = page.title.copy
31
- further_research_title.name = 'h3'
32
- further_research_title.replace_children(with: <<~HTML
33
- <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
34
- <span class="os-divider"> </span>
35
- <span class="os-text" data-type="" itemprop="">#{further_research_title.children}</span>
36
- HTML
37
- )
38
-
39
- further_research.prepend(child:
40
- <<~HTML
41
- <a href="##{page.title.id}">
42
- #{further_research_title.paste}
43
- </a>
44
- HTML
45
- )
46
- further_research.cut(to: further_researches)
17
+ MoveCustomSectionToEocContainer.v1(
18
+ chapter: chapter,
19
+ metadata_source: metadata_source,
20
+ container_key: 'further-research',
21
+ uuid_key: "#{uuid_prefix}further-research",
22
+ section_selector: 'section.further-research',
23
+ append_to: nil,
24
+ include_intro_page: false
25
+ ) do |further_research|
26
+ RemoveSectionTitle.v1(section: further_research)
27
+ title = EocSectionTitleLinkSnippet.v1(page: further_research.ancestor(:page))
28
+ further_research.prepend(child: title)
29
+ further_research.first('h3')[:itemprop] = 'name'
47
30
  end
48
-
49
- return if further_researches.none?
50
-
51
- @content = further_researches.paste
52
-
53
- @in_composite_chapter = false
54
-
55
- chapter.append(child: render(file:
56
- '../templates/eoc_section_title_template.xhtml.erb'))
57
31
  end
58
32
  end
59
33
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ # Bakes inline lists with the desired list separator
6
+ # Does not separate the last list item
7
+ #
8
+ module BakeInlineLists
9
+ LIST_SEPARATOR = '; '
10
+ SEPARATOR_CLASS = '-os-inline-list-separator'
11
+
12
+ def self.v1(book:)
13
+ inline_lists = book.search('span[data-display="inline"][data-type="list"]')
14
+ inline_lists.each do |list|
15
+ list.search('span[data-type="item"]')[0..-2].each do |item|
16
+ item.append(child: "<span class=\"#{SEPARATOR_CLASS}\">#{LIST_SEPARATOR}</span>")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -11,6 +11,13 @@ module Kitchen
11
11
  metadata_source: metadata_source
12
12
  )
13
13
  end
14
+
15
+ def self.v2(book:, metadata_source:)
16
+ V2.new.bake(
17
+ book: book,
18
+ metadata_source: metadata_source
19
+ )
20
+ end
14
21
  end
15
22
  end
16
23
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeReferences
4
+ class V2
5
+ renderable
6
+
7
+ def bake(book:, metadata_source:)
8
+ @metadata = metadata_source.children_to_keep.copy
9
+ @klass = 'references'
10
+ @uuid_prefix = '.'
11
+ @title = I18n.t(:references)
12
+
13
+ book.chapters.each do |chapter|
14
+
15
+ chapter.references.search('h3').trash
16
+
17
+ chapter_references = chapter.pages.references.cut
18
+ chapter_title_no_num = chapter.title.search('.os-text')
19
+
20
+ chapter.append(child:
21
+ <<~HTML
22
+ <div class="os-chapter-area">
23
+ <h2 data-type="document-title">#{chapter_title_no_num}</h2>
24
+ #{chapter_references.paste}
25
+ </div>
26
+ HTML
27
+ )
28
+ end
29
+ chapter_area_references = book.chapters.search('.os-chapter-area').cut
30
+ @content = chapter_area_references.paste
31
+ book.body.append(child: render(file:
32
+ '../../templates/eob_section_title_template.xhtml.erb'))
33
+ end
34
+ end
35
+ end
@@ -96,8 +96,10 @@ module Kitchen
96
96
  when CompositePageElement
97
97
  if page.is_index?
98
98
  'os-toc-index'
99
- elsif page.is_reference?
99
+ elsif page.is_citation_reference?
100
100
  'os-toc-reference'
101
+ elsif page.is_section_reference?
102
+ 'os-toc-references'
101
103
  elsif page.has_ancestor?(:composite_chapter) || page.has_ancestor?(:chapter)
102
104
  'os-toc-chapter-composite-page'
103
105
  else
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module EocCompositePageContainer
6
+ # Creates a wrapper for the given content & appends it to the given element
7
+ #
8
+ # @param container_key [String] Appended to 'eoc.' to form the I18n key for the container title; also used as part of a class on the container.
9
+ # @param uuid_key [String] the uuid key for the wrapper class, e.g. `'.summary'`
10
+ # @param metadata_source [MetadataElement] metadata for the book
11
+ # @param content [String] the content to be contained by the wrapper
12
+ # @param append_to [ElementBase] the element to be appended, usually either a `ChapterElement` or a `CompositeChapterElement`
13
+ # @return [ElementBase] the append_to element with container appended
14
+ #
15
+ def self.v1(container_key:, uuid_key:, metadata_source:, content:,
16
+ append_to:)
17
+ V1.new.bake(
18
+ container_key: container_key,
19
+ uuid_key: uuid_key,
20
+ metadata_source: metadata_source,
21
+ content: content,
22
+ append_to: append_to
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::EocCompositePageContainer
4
+ class V1
5
+ renderable
6
+
7
+ def bake(container_key:, uuid_key:, metadata_source:, content:, append_to:)
8
+ @title = I18n.t(:"eoc.#{container_key}")
9
+ @uuid_key = uuid_key
10
+ @container_class_type = container_key
11
+ @metadata = metadata_source.children_to_keep.copy
12
+ @content = content
13
+ @in_composite_chapter = append_to.is?(:composite_chapter)
14
+
15
+ append_to.append(child: render(file:
16
+ '../../templates/eoc_section_template.xhtml.erb'))
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/ParameterLists
4
+ # More parameters are ok here because these generic classes DRY up a lot of other code
5
+ module Kitchen
6
+ module Directions
7
+ module MoveCustomSectionToEocContainer
8
+ # Creates a custom eoc composite page for a section within the given chapter.
9
+ # The sections are moved into this composite page, and can be transformed before the moved by an optional block argument.
10
+ #
11
+ # @param chapter [ChapterElement] the chapter in which the section to be moved is contained
12
+ # @param metadata_source [MetadataElement] metadata for the book
13
+ # @param container_key [String] Appended to 'eoc.' to form the I18n key for the container title; also used as part of a class on the container.
14
+ # @param uuid_key [String] the uuid key for the wrapper class, e.g. `'.summary'`
15
+ # @param section_selector [String] the selector for the section to be moved, e.g. `'section.summary'`
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
+ # @return [ElementBase] the append_to element with container appended
19
+ #
20
+ def self.v1(chapter:, metadata_source:, container_key:, uuid_key:,
21
+ section_selector:, append_to: nil, include_intro_page: true)
22
+ V1.new.bake(
23
+ chapter: chapter,
24
+ metadata_source: metadata_source,
25
+ container_key: container_key,
26
+ uuid_key: uuid_key,
27
+ section_selector: section_selector,
28
+ append_to: append_to || chapter,
29
+ include_intro_page: include_intro_page
30
+ ) do |section|
31
+ yield section if block_given?
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ # rubocop:enable Metrics/ParameterLists
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/ParameterLists
4
+ # More parameters are ok here because these generic classes DRY up a lot of other code
5
+ module Kitchen::Directions::MoveCustomSectionToEocContainer
6
+ class V1
7
+ def bake(chapter:, metadata_source:, container_key:, uuid_key:,
8
+ section_selector:, append_to:, include_intro_page:, &block)
9
+ section_clipboard = Kitchen::Clipboard.new
10
+ pages = include_intro_page ? chapter.pages : chapter.non_introduction_pages
11
+ sections = pages.search(section_selector)
12
+ sections.each(&block)
13
+ sections.cut(to: section_clipboard)
14
+
15
+ return if section_clipboard.none?
16
+
17
+ Kitchen::Directions::EocCompositePageContainer.v1(
18
+ container_key: container_key,
19
+ uuid_key: uuid_key,
20
+ metadata_source: metadata_source,
21
+ content: section_clipboard.paste,
22
+ append_to: append_to || chapter
23
+ )
24
+ end
25
+ end
26
+ end
27
+ # rubocop:enable Metrics/ParameterLists
@@ -2,35 +2,18 @@
2
2
 
3
3
  module Kitchen::Directions::MoveExercisesToEOC
4
4
  class V1
5
- renderable
6
-
7
5
  def bake(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
8
- @klass = klass
9
- @metadata = metadata_source.children_to_keep.copy
10
- @title = I18n.t(:"eoc.#{klass}")
11
- @uuid_prefix = uuid_prefix
12
-
13
- exercise_clipboard = Kitchen::Clipboard.new
14
-
15
- chapter.non_introduction_pages.each do |page|
16
- sections = page.search("section.#{@klass}")
17
-
18
- sections.each do |exercise_section|
19
- exercise_section.first("[data-type='title']")&.trash
20
-
21
- exercise_section.cut(to: exercise_clipboard)
22
- end
6
+ Kitchen::Directions::MoveCustomSectionToEocContainer.v1(
7
+ chapter: chapter,
8
+ metadata_source: metadata_source,
9
+ container_key: klass,
10
+ uuid_key: "#{uuid_prefix}#{klass}",
11
+ section_selector: "section.#{klass}",
12
+ append_to: append_to || chapter,
13
+ include_intro_page: false
14
+ ) do |exercise_section|
15
+ Kitchen::Directions::RemoveSectionTitle.v1(section: exercise_section)
23
16
  end
24
-
25
- return if exercise_clipboard.none?
26
-
27
- @content = exercise_clipboard.paste
28
-
29
- append_to_element = append_to || chapter
30
- @in_composite_chapter = append_to_element.is?(:composite_chapter)
31
-
32
- append_to_element.append(child: render(file:
33
- '../../templates/eoc_section_title_template.xhtml.erb'))
34
17
  end
35
18
  end
36
19
  end
@@ -4,25 +4,16 @@ module Kitchen::Directions::MoveExercisesToEOC
4
4
  # Main difference from v1 is the presence of a section title
5
5
  # and some additional wrappers
6
6
  class V2
7
- renderable
8
-
9
7
  def bake(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
10
- @klass = klass
11
- @metadata = metadata_source.children_to_keep.copy
12
- @title = I18n.t(:"eoc.#{klass}")
13
- @uuid_prefix = uuid_prefix
14
-
15
8
  exercise_clipboard = Kitchen::Clipboard.new
16
9
 
17
10
  chapter.non_introduction_pages.each do |page|
18
- sections = page.search("section.#{@klass}")
11
+ sections = page.search("section.#{klass}")
19
12
 
20
13
  sections.each do |exercise_section|
21
- exercise_section.first("[data-type='title']")&.trash
22
-
14
+ Kitchen::Directions::RemoveSectionTitle.v1(section: exercise_section)
23
15
  # Get parent page title
24
16
  section_title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
25
-
26
17
  # Configure section title & wrappers
27
18
  exercise_section.prepend(child: section_title)
28
19
  exercise_section.wrap('<div class="os-section-area">')
@@ -33,17 +24,19 @@ module Kitchen::Directions::MoveExercisesToEOC
33
24
 
34
25
  return if exercise_clipboard.none?
35
26
 
36
- @content = <<~HTML
37
- <div class="os-#{@klass}">
27
+ content = <<~HTML
28
+ <div class="os-#{klass}">
38
29
  #{exercise_clipboard.paste}
39
30
  </div>
40
31
  HTML
41
32
 
42
- append_to_element = append_to || chapter
43
- @in_composite_chapter = append_to_element[:'data-type'] == 'composite-chapter'
44
-
45
- append_to_element.append(child: render(file:
46
- '../../templates/eoc_section_title_template.xhtml.erb'))
33
+ Kitchen::Directions::EocCompositePageContainer.v1(
34
+ container_key: klass,
35
+ uuid_key: "#{uuid_prefix}#{klass}",
36
+ metadata_source: metadata_source,
37
+ content: content,
38
+ append_to: append_to || chapter
39
+ )
47
40
  end
48
41
  end
49
42
  end
@@ -4,46 +4,22 @@ module Kitchen::Directions::MoveExercisesToEOC
4
4
  # The difference from v1 is the presence of a section title
5
5
  # and from v2 the lack of additional "os-section-area" and os-#{@klass} wrappers
6
6
  class V3
7
- renderable
8
-
9
7
  def bake(chapter:, metadata_source:, klass:, append_to: nil, uuid_prefix: '.')
10
- @klass = klass
11
- @metadata = metadata_source.children_to_keep.copy
12
- @title = I18n.t(:"eoc.#{klass}")
13
- @uuid_prefix = uuid_prefix
14
-
15
- exercise_clipboard = Kitchen::Clipboard.new
16
-
17
- chapter.non_introduction_pages.each do |page|
18
- sections = page.search("section.#{@klass}")
19
-
20
- sections.each do |exercise_section|
21
- exercise_section.first("[data-type='title']")&.trash
22
-
23
- section_title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
24
-
25
- exercise_section.exercises.each do |exercise|
26
- exercise.document.pantry(name: :link_text).store(
27
- "#{I18n.t(:exercise_label)} #{chapter.count_in(:book)}.#{exercise.count_in(:chapter)}",
28
- label: exercise.id
29
- )
30
- end
31
-
32
- # Configure section title
33
- exercise_section.prepend(child: section_title)
34
- exercise_section.cut(to: exercise_clipboard)
35
- end
8
+ Kitchen::Directions::MoveCustomSectionToEocContainer.v1(
9
+ chapter: chapter,
10
+ metadata_source: metadata_source,
11
+ container_key: klass,
12
+ uuid_key: "#{uuid_prefix}#{klass}",
13
+ section_selector: "section.#{klass}",
14
+ append_to: append_to || chapter,
15
+ include_intro_page: false
16
+ ) do |exercise_section|
17
+ Kitchen::Directions::RemoveSectionTitle.v1(section: exercise_section)
18
+ title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(
19
+ page: exercise_section.ancestor(:page)
20
+ )
21
+ exercise_section.prepend(child: title)
36
22
  end
37
-
38
- return if exercise_clipboard.none?
39
-
40
- @content = exercise_clipboard.paste
41
-
42
- append_to_element = append_to || chapter
43
- @in_composite_chapter = append_to_element.is?(:composite_chapter)
44
-
45
- append_to_element.append(child: render(file:
46
- '../../templates/eoc_section_title_template.xhtml.erb'))
47
23
  end
48
24
  end
49
25
  end