openstax_kitchen 13.0.0 → 14.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0f1212b9bee542b587323cef1fa5ff8dc7437d47921736f58c9c27ef6ee11b8
4
- data.tar.gz: ca01c38368dc34a0e637f431caf7873f97d5dd52b465e1ae5411d6f0861b8e58
3
+ metadata.gz: fe096a5d1994a88a6a1e3d0d585bc76ff216157550eec29df3a37da3aa36f229
4
+ data.tar.gz: 38f20f8be2ae246005c047ea0702e0e2a266b039e534fe0b063157054609873d
5
5
  SHA512:
6
- metadata.gz: c877a0d30bde86ccc5d0e2191b3e0efe853916294d907c764a088e67a2011f9f3fa03fb018ff8aa9992e1fbaeebb753625b90f593d888d8e8a4473139e9e0f43
7
- data.tar.gz: f96e5128a718bf1897c65b5b558d2586e6905767e355cf9119c56b536f128bbbf403c658187e6faefc0bb7e7fc3013218353a81d99c1fc8dfc30a9ffed8354db
6
+ metadata.gz: 20d6729f702ada57a80cf10bf5851562e1649e10ff002f98dc56a30f438aecee2b242e7a377af49313344b73b604d690eb2c8f7acd903cddafd32a0b7505fc2f
7
+ data.tar.gz: bf8d77b0693a23cc1332d5c40c6eea39aeed0e1b1cb3c83017d60ad3541280c210fde867063551c52afe5e76198add5cfd5af960ab55b3f0cd617492e262658c
data/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [14.0.0] - 2021-10-22
10
+
11
+ Fix `BakeAutotitledExercise` V2 to stop breaking for exercises without solutions (patch)
12
+ Add `BakeAutotitledExercise` V2 (minor)
13
+ Fix `BakeChapterGlossary::V1` to stop adding an empty wrapper if there is no content (patch)
14
+ * Create `BakeNoteExercise` and `BakeNoteInjectedQuestion` and support exercises in `BakeUnclassifiedNotes` (minor)
15
+ * Add baking section with class `column header` to `BakeAppendix` (patch)
16
+ * Expand `BakeAnnotationClasses` to book from chapter to bake also paragraphs from Preface (major)
17
+ * Create separate direction `BakeUnnumberedFigure`, clean `BakeFigure` to not match unnumbered figures , rename and update `figure_to_bake?` method to `figure_to_number?` to support only numbered figures except subfigures (major)
9
18
 
10
19
  ## [13.0.0] - 2021-10-6
11
20
 
data/Gemfile CHANGED
@@ -9,3 +9,4 @@ gem 'rake', '~> 12.0'
9
9
  gem 'rspec', '~> 3.0'
10
10
 
11
11
  gem 'codecov', require: false
12
+
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openstax_kitchen (13.0.0)
4
+ openstax_kitchen (14.0.0)
5
5
  activesupport
6
6
  i18n
7
7
  nokogiri
@@ -107,7 +107,7 @@ GEM
107
107
  concurrent-ruby (~> 1.0)
108
108
  unicode-display_width (1.7.0)
109
109
  yard (0.9.24)
110
- zeitwerk (2.4.2)
110
+ zeitwerk (2.5.1)
111
111
 
112
112
  PLATFORMS
113
113
  ruby
@@ -3,9 +3,9 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeAnnotationClasses
6
- def self.v1(chapter:)
6
+ def self.v1(book:)
7
7
  V1.new.bake(
8
- chapter: chapter)
8
+ book: book)
9
9
  end
10
10
  end
11
11
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Kitchen::Directions::BakeAnnotationClasses
4
4
  class V1
5
- def bake(chapter:)
6
- chapter.search('p.annotation').each do |annotation|
5
+ def bake(book:)
6
+ book.search('p.annotation').each do |annotation|
7
7
  annotation.wrap_children('span', class: 'os-text')
8
8
  annotation.prepend(child:
9
9
  <<~HTML
@@ -19,7 +19,7 @@ module Kitchen::Directions::BakeAnnotationClasses
19
19
  auditory-icon
20
20
  kinesthetic-icon]
21
21
  annotation_icon_classes.each do |annotation_icon_class|
22
- chapter.search("p.#{annotation_icon_class}").each do |annotation_with_icon_class|
22
+ book.search("p.#{annotation_icon_class}").each do |annotation_with_icon_class|
23
23
  annotation_with_icon_class.search('div.os-icons').first.append(child:
24
24
  <<~HTML
25
25
  <span class = "#{annotation_icon_class}"></span>
@@ -21,6 +21,7 @@ module Kitchen
21
21
  next unless title.present?
22
22
 
23
23
  title.name = "h#{section['data-depth'].to_i + 1}"
24
+ section.name = 'div' if section.has_class?('column-container')
24
25
  end
25
26
  end
26
27
  end
@@ -6,6 +6,10 @@ module Kitchen
6
6
  def self.v1(exercise:, number: nil)
7
7
  V1.new.bake(exercise: exercise, number: number)
8
8
  end
9
+
10
+ def self.v2(exercise:, title:)
11
+ V2.new.bake(exercise: exercise, title: title)
12
+ end
9
13
  end
10
14
  end
11
15
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeAutotitledExercise
4
+ # Differences from V1:
5
+ # 1. Title is an <h3><span>, not <h4>, & above the problem instead of within it
6
+ # 2. Title is generated in the recipe and passed to the method
7
+ class V2
8
+ def bake(exercise:, title:)
9
+ exercise.add_class('unnumbered')
10
+ exercise.titles.first&.trash
11
+
12
+ # bake problem
13
+ exercise.prepend(child:
14
+ <<~HTML
15
+ <h3 class="os-title" data-type="title">
16
+ <span class="os-title-label">#{title}</span>
17
+ </h3>
18
+ HTML
19
+ )
20
+ exercise.problem.wrap_children(class: 'os-problem-container')
21
+ return unless exercise.solution
22
+
23
+ exercise.solution.wrap_children(class: 'os-solution-container')
24
+ exercise.solution.prepend(child:
25
+ <<~HTML
26
+ <h4 class="solution-title" data-type="title">
27
+ <span class="os-text">#{I18n.t(:solution)}</span>
28
+ </h4>
29
+ HTML
30
+ )
31
+ end
32
+ end
33
+ end
@@ -41,6 +41,8 @@ module Kitchen::Directions::BakeChapterGlossary
41
41
 
42
42
  content = @glossary.sort.map { |definition| definition.element.paste }.join
43
43
 
44
+ return if content.empty?
45
+
44
46
  Kitchen::Directions::CompositePageContainer.v1(
45
47
  container_key: 'glossary',
46
48
  uuid_key: "#{uuid_prefix}glossary",
@@ -4,27 +4,13 @@ module Kitchen
4
4
  module Directions
5
5
  module BakeFigure
6
6
  def self.v1(figure:, number:, cases: false)
7
- return if figure.has_class?('unnumbered') && !figure.has_class?('splash') && !figure.caption
8
-
7
+ warn 'warning! exclude unnumbered figures from `BakeFigure` loop' if figure.unnumbered?
9
8
  figure.wrap(%(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
10
9
 
11
- if figure.has_class?('unnumbered') && (figure.caption || figure.has_class?('splash'))
12
- caption = figure.caption&.cut
13
- figure.append(sibling:
14
- <<~HTML
15
- <div class="os-caption-container">
16
- #{"<span class=\"os-caption\">#{caption.children}</span>" if caption}
17
- </div>
18
- HTML
19
- )
20
- return
21
- end
22
-
23
10
  # Store label information
24
11
  figure.target_label(label_text: 'figure', custom_content: number, cases: cases)
25
12
 
26
13
  title = figure.title&.cut
27
-
28
14
  caption = figure.caption&.cut
29
15
  figure.append(sibling:
30
16
  <<~HTML
@@ -30,32 +30,7 @@ module Kitchen
30
30
  HTML
31
31
  )
32
32
 
33
- bake_unclassified_exercises(note: note) if bake_exercises
34
- end
35
-
36
- def self.bake_unclassified_exercises(note:)
37
- note.exercises.each do |exercise|
38
- exercise.problem.wrap_children('div', class: 'os-problem-container')
39
-
40
- unless exercise.has_class?('unnumbered')
41
- exercise.problem.prepend(child:
42
- <<~HTML
43
- <span class="os-title-label">#{I18n.t(:"exercises.exercise")} </span>
44
- <span class="os-number">#{exercise.count_in(:note)}</span>
45
- HTML
46
- )
47
- end
48
-
49
- next unless exercise.solution
50
-
51
- exercise.solution.wrap_children('div', class: 'os-solution-container')
52
-
53
- exercise.solution.prepend(child:
54
- <<~HTML
55
- <span class="os-title-label">#{I18n.t(:"exercises.solution")}</span>
56
- HTML
57
- )
58
- end
33
+ BakeNoteExercise.v2(note: note) if bake_exercises
59
34
  end
60
35
  end
61
36
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeNoteExercise
6
+ def self.v1(note:, exercise:, divider: ' ', suppress_solution: false)
7
+ exercise.add_class('unnumbered')
8
+ number = note.first('.os-number').text.gsub(/#/, '')
9
+
10
+ # bake problem
11
+ exercise.problem.wrap_children('div', class: 'os-problem-container')
12
+ exercise.search('[data-type="commentary"]').each(&:trash)
13
+ return unless exercise.solution
14
+
15
+ # bake solution in place
16
+ if suppress_solution
17
+ exercise.add_class('os-hasSolution')
18
+ exercise.solution.trash
19
+ else
20
+ BakeNumberedExercise.bake_solution_v1(
21
+ exercise: exercise,
22
+ number: number,
23
+ divider: divider
24
+ )
25
+ end
26
+ end
27
+
28
+ def self.v2(note:)
29
+ note.exercises.each do |exercise|
30
+ exercise.problem.wrap_children('div', class: 'os-problem-container')
31
+
32
+ unless exercise.has_class?('unnumbered')
33
+ exercise.problem.prepend(child:
34
+ <<~HTML
35
+ <span class="os-title-label">#{I18n.t(:"exercises.exercise")} </span>
36
+ <span class="os-number">#{exercise.count_in(:note)}</span>
37
+ HTML
38
+ )
39
+ end
40
+
41
+ next unless exercise.solution
42
+
43
+ exercise.solution.wrap_children('div', class: 'os-solution-container')
44
+
45
+ exercise.solution.prepend(child:
46
+ <<~HTML
47
+ <span class="os-title-label">#{I18n.t(:"exercises.solution")}</span>
48
+ HTML
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeNoteInjectedQuestion
6
+ def self.v1(note:, question:)
7
+ question.add_class('unnumbered')
8
+ number = note.first('.os-number').text.gsub(/#/, '')
9
+ Kitchen::Directions::BakeInjectedExerciseQuestion.v1(
10
+ question: question, number: number, only_number_solution: true
11
+ )
12
+ end
13
+ end
14
+ end
15
+ end
@@ -17,37 +17,6 @@ module Kitchen
17
17
  def self.v3(book:, classes:, suppress_solution: true)
18
18
  V3.new.bake(book: book, classes: classes, suppress_solution: suppress_solution)
19
19
  end
20
-
21
- # Used by V1, V2, V3
22
- def self.bake_note_exercise(note:, exercise:, divider: ' ', suppress_solution: false)
23
- exercise.add_class('unnumbered')
24
- number = note.first('.os-number').text.gsub(/#/, '')
25
-
26
- # bake problem
27
- exercise.problem.wrap_children('div', class: 'os-problem-container')
28
- exercise.search('[data-type="commentary"]').each(&:trash)
29
- return unless exercise.solution
30
-
31
- # bake solution in place
32
- if suppress_solution
33
- exercise.add_class('os-hasSolution')
34
- exercise.solution.trash
35
- else
36
- BakeNumberedExercise.bake_solution_v1(
37
- exercise: exercise,
38
- number: number,
39
- divider: divider
40
- )
41
- end
42
- end
43
-
44
- def self.bake_note_injected_question(note:, question:)
45
- question.add_class('unnumbered')
46
- number = note.first('.os-number').text.gsub(/#/, '')
47
- Kitchen::Directions::BakeInjectedExerciseQuestion.v1(
48
- question: question, number: number, only_number_solution: true
49
- )
50
- end
51
20
  end
52
21
  end
53
22
  end
@@ -8,10 +8,10 @@ module Kitchen::Directions
8
8
  book.chapters.pages.notes("$.#{klass}").each do |note|
9
9
  bake_note(note: note, cases: cases)
10
10
  note.exercises.each do |exercise|
11
- BakeNumberedNotes.bake_note_exercise(note: note, exercise: exercise)
11
+ BakeNoteExercise.v1(note: note, exercise: exercise)
12
12
  end
13
13
  note.injected_questions.each do |question|
14
- BakeNumberedNotes.bake_note_injected_question(note: note, question: question)
14
+ BakeNoteInjectedQuestion.v1(note: note, question: question)
15
15
  end
16
16
  end
17
17
  end
@@ -17,10 +17,10 @@ module Kitchen::Directions
17
17
  HTML
18
18
  )
19
19
  note.exercises.each do |exercise|
20
- BakeNumberedNotes.bake_note_exercise(note: note, exercise: exercise, divider: '. ')
20
+ BakeNoteExercise.v1(note: note, exercise: exercise, divider: '. ')
21
21
  end
22
22
  note.injected_questions.each do |question|
23
- BakeNumberedNotes.bake_note_injected_question(note: note, question: question)
23
+ BakeNoteInjectedQuestion.v1(note: note, question: question)
24
24
  end
25
25
  end
26
26
  end
@@ -25,12 +25,12 @@ module Kitchen::Directions
25
25
 
26
26
  note.title&.trash
27
27
  note.exercises.each do |exercise|
28
- BakeNumberedNotes.bake_note_exercise(
28
+ BakeNoteExercise.v1(
29
29
  note: note, exercise: exercise, divider: '. ', suppress_solution: suppress_solution
30
30
  )
31
31
  end
32
32
  note.injected_questions.each do |question|
33
- BakeNumberedNotes.bake_note_injected_question(note: note, question: question)
33
+ BakeNoteInjectedQuestion.v1(note: note, question: question)
34
34
  end
35
35
 
36
36
  note.search("div[data-type='solution']").each&.trash if suppress_solution
@@ -3,15 +3,15 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeUnclassifiedNotes
6
- def self.v1(book:)
6
+ def self.v1(book:, bake_exercises: false)
7
7
  book.notes.each do |note|
8
8
  next unless note.classes.empty?
9
9
 
10
- bake_note(note: note)
10
+ bake_note(note: note, bake_exercises: bake_exercises)
11
11
  end
12
12
  end
13
13
 
14
- def self.bake_note(note:)
14
+ def self.bake_note(note:, bake_exercises:)
15
15
  note.wrap_children(class: 'os-note-body')
16
16
 
17
17
  title = note.title&.cut
@@ -24,6 +24,8 @@ module Kitchen
24
24
  </h3>
25
25
  HTML
26
26
  )
27
+
28
+ BakeNoteExercise.v2(note: note) if bake_exercises
27
29
  end
28
30
  end
29
31
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeUnnumberedFigure
6
+ def self.v1(book:)
7
+ book.figures(only: :unnumbered?).each do |figure|
8
+ next unless figure.caption || figure.title
9
+
10
+ figure.wrap(%(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
11
+ title = figure.title&.cut
12
+ caption = figure.caption&.cut
13
+ figure.append(sibling:
14
+ <<~HTML
15
+ <div class="os-caption-container">
16
+ #{"<span class=\"os-title\" data-type=\"title\" id=\"#{title.id}\">#{title.children}</span>" if title}
17
+ #{'<span class="os-divider"> </span>' if title && caption}
18
+ #{"<span class=\"os-caption\">#{caption.children}</span>" if caption}
19
+ </div>
20
+ HTML
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -47,16 +47,24 @@ module Kitchen
47
47
  parent.name == 'figure'
48
48
  end
49
49
 
50
+ # Returns true if the figure is unnumbered
51
+ #
52
+ # @return [Boolean]
53
+ #
54
+
55
+ def unnumbered?
56
+ has_class?('unnumbered')
57
+ end
58
+
50
59
  # Returns true unless the figure is a subfigure or has the 'unnumbered' class,
51
60
  # unless the figure has both the 'unnumbered' and the 'splash' classes.
52
61
  #
53
62
  # @return [Boolean]
54
- #
55
- def figure_to_bake?
56
- return false if subfigure? || (has_class?('unnumbered') && !has_class?('splash') && !caption)
63
+
64
+ def figure_to_number?
65
+ return false if subfigure? || unnumbered?
57
66
 
58
67
  true
59
68
  end
60
-
61
69
  end
62
70
  end
@@ -3,5 +3,5 @@
3
3
  # A library for modifying the structure of OpenStax book XML.
4
4
  #
5
5
  module Kitchen
6
- VERSION = '13.0.0'
6
+ VERSION = '14.0.0'
7
7
  end
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: 13.0.0
4
+ version: 14.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-10-06 00:00:00.000000000 Z
11
+ date: 2021-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -249,6 +249,7 @@ files:
249
249
  - lib/kitchen/directions/bake_appendix.rb
250
250
  - lib/kitchen/directions/bake_autotitled_exercise/main.rb
251
251
  - lib/kitchen/directions/bake_autotitled_exercise/v1.rb
252
+ - lib/kitchen/directions/bake_autotitled_exercise/v2.rb
252
253
  - lib/kitchen/directions/bake_chapter_glossary/main.rb
253
254
  - lib/kitchen/directions/bake_chapter_glossary/v1.rb
254
255
  - lib/kitchen/directions/bake_chapter_introductions/bake_chapter_objectives.rb
@@ -303,6 +304,8 @@ files:
303
304
  - lib/kitchen/directions/bake_math_in_paragraph.rb
304
305
  - lib/kitchen/directions/bake_non_introduction_pages.rb
305
306
  - lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb
307
+ - lib/kitchen/directions/bake_notes/bake_note_exercise.rb
308
+ - lib/kitchen/directions/bake_notes/bake_note_injected_question.rb
306
309
  - lib/kitchen/directions/bake_notes/bake_note_subtitle.rb
307
310
  - lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb
308
311
  - lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb
@@ -328,6 +331,7 @@ files:
328
331
  - lib/kitchen/directions/bake_unit_page_title/v1.rb
329
332
  - lib/kitchen/directions/bake_unit_title/main.rb
330
333
  - lib/kitchen/directions/bake_unit_title/v1.rb
334
+ - lib/kitchen/directions/bake_unnumbered_figure.rb
331
335
  - lib/kitchen/directions/bake_unnumbered_tables.rb
332
336
  - lib/kitchen/directions/book_answer_key_container/eob_answer_key_outer_container.xhtml.erb
333
337
  - lib/kitchen/directions/book_answer_key_container/main.rb