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 +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -2
- data/lib/kitchen/directions/bake_annotation_classes/main.rb +2 -2
- data/lib/kitchen/directions/bake_annotation_classes/v1.rb +3 -3
- data/lib/kitchen/directions/bake_appendix.rb +1 -0
- data/lib/kitchen/directions/bake_autotitled_exercise/main.rb +4 -0
- data/lib/kitchen/directions/bake_autotitled_exercise/v2.rb +33 -0
- data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +2 -0
- data/lib/kitchen/directions/bake_figure.rb +1 -15
- data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +1 -26
- data/lib/kitchen/directions/bake_notes/bake_note_exercise.rb +54 -0
- data/lib/kitchen/directions/bake_notes/bake_note_injected_question.rb +15 -0
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb +0 -31
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb +2 -2
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v2.rb +2 -2
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +2 -2
- data/lib/kitchen/directions/bake_notes/bake_unclassified_notes.rb +5 -3
- data/lib/kitchen/directions/bake_unnumbered_figure.rb +26 -0
- data/lib/kitchen/figure_element.rb +12 -4
- data/lib/kitchen/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe096a5d1994a88a6a1e3d0d585bc76ff216157550eec29df3a37da3aa36f229
|
4
|
+
data.tar.gz: 38f20f8be2ae246005c047ea0702e0e2a266b039e534fe0b063157054609873d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openstax_kitchen (
|
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.
|
110
|
+
zeitwerk (2.5.1)
|
111
111
|
|
112
112
|
PLATFORMS
|
113
113
|
ruby
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Kitchen::Directions::BakeAnnotationClasses
|
4
4
|
class V1
|
5
|
-
def bake(
|
6
|
-
|
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
|
-
|
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>
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
11
|
+
BakeNoteExercise.v1(note: note, exercise: exercise)
|
12
12
|
end
|
13
13
|
note.injected_questions.each do |question|
|
14
|
-
|
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
|
-
|
20
|
+
BakeNoteExercise.v1(note: note, exercise: exercise, divider: '. ')
|
21
21
|
end
|
22
22
|
note.injected_questions.each do |question|
|
23
|
-
|
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
|
-
|
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
|
-
|
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
|
56
|
-
return false if subfigure? ||
|
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
|
data/lib/kitchen/version.rb
CHANGED
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:
|
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-
|
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
|