openstax_kitchen 5.0.0 → 6.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/.github/workflows/changelog.yml +27 -0
- data/.github/workflows/rubocop.yml +28 -0
- data/CHANGELOG.md +33 -0
- data/Gemfile.lock +8 -6
- data/docker/rubocop +22 -0
- data/lib/kitchen/directions/bake_appendix.rb +3 -1
- data/lib/kitchen/directions/bake_chapter_introductions.rb +22 -15
- data/lib/kitchen/directions/bake_chapter_introductions/chapter_introduction.xhtml.erb +0 -0
- data/lib/kitchen/directions/bake_chapter_section_exercises/main.rb +2 -2
- data/lib/kitchen/directions/bake_chapter_section_exercises/v1.rb +2 -1
- data/lib/kitchen/directions/bake_chapter_solutions/main.rb +11 -0
- data/lib/kitchen/directions/bake_chapter_solutions/v1.rb +37 -0
- data/lib/kitchen/directions/bake_chapter_summary.rb +13 -6
- data/lib/kitchen/directions/bake_example.rb +4 -1
- data/lib/kitchen/directions/bake_figure.rb +13 -0
- data/lib/kitchen/directions/bake_footnotes/main.rb +2 -2
- data/lib/kitchen/directions/bake_footnotes/v1.rb +11 -8
- data/lib/kitchen/directions/bake_further_research.rb +2 -0
- data/lib/kitchen/directions/bake_index/v1.rb +2 -2
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb +43 -0
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb +37 -0
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v2.rb +25 -0
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +32 -0
- data/lib/kitchen/directions/bake_numbered_exercise/main.rb +3 -2
- data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +10 -1
- data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +29 -0
- data/lib/kitchen/directions/bake_numbered_table/main.rb +4 -0
- data/lib/kitchen/directions/bake_numbered_table/v1.rb +1 -17
- data/lib/kitchen/directions/bake_numbered_table/v2.rb +31 -0
- data/lib/kitchen/directions/bake_preface/main.rb +2 -2
- data/lib/kitchen/directions/bake_preface/v1.rb +3 -2
- data/lib/kitchen/directions/book_answer_key_container/eob_answer_key_outer_container.xhtml.erb +9 -0
- data/lib/kitchen/directions/book_answer_key_container/main.rb +2 -2
- data/lib/kitchen/directions/book_answer_key_container/v1.rb +4 -3
- data/lib/kitchen/directions/chapter_review_container/chapter_review.xhtml.erb +3 -3
- data/lib/kitchen/directions/chapter_review_container/main.rb +2 -2
- data/lib/kitchen/directions/chapter_review_container/v1.rb +4 -2
- data/lib/kitchen/directions/eoc_section_title_link_snippet.rb +13 -0
- data/lib/kitchen/directions/move_exercises_to_eoc/main.rb +10 -0
- data/lib/kitchen/directions/move_exercises_to_eoc/v3.rb +49 -0
- data/lib/kitchen/directions/move_solutions_to_answer_key/main.rb +6 -2
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/default.rb +27 -0
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/precalculus.rb +84 -0
- data/lib/kitchen/directions/move_solutions_to_answer_key/v1.rb +11 -7
- data/lib/kitchen/element_base.rb +15 -0
- data/lib/kitchen/page_element.rb +2 -3
- data/lib/kitchen/patches/integer.rb +24 -0
- data/lib/kitchen/patches/nokogiri.rb +7 -0
- data/lib/kitchen/version.rb +1 -1
- data/lib/locales/en.yml +2 -1
- data/lib/locales/es.yml +2 -1
- data/lib/locales/pl.yml +3 -2
- metadata +19 -6
- data/.github/config.yml +0 -14
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes.rb +0 -51
- data/lib/kitchen/directions/book_answer_key_container/eob_solutions_container.xhtml.erb +0 -9
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/american_government.rb +0 -19
@@ -24,6 +24,8 @@ module Kitchen
|
|
24
24
|
|
25
25
|
chapter.non_introduction_pages.each do |page|
|
26
26
|
further_research = page.first('.further-research')
|
27
|
+
next unless further_research.present?
|
28
|
+
|
27
29
|
further_research.first("[data-type='title']")&.trash # get rid of old title if exists
|
28
30
|
further_research_title = page.title.copy
|
29
31
|
further_research_title.name = 'h3'
|
@@ -136,8 +136,8 @@ module Kitchen::Directions::BakeIndex
|
|
136
136
|
end
|
137
137
|
|
138
138
|
def add_term_to_index(term_element, page_title)
|
139
|
-
group_by = term_element.text.strip[0]
|
140
|
-
group_by = I18n.t(:eob_index_symbols_group) unless group_by.match?(
|
139
|
+
group_by = I18n.transliterate(term_element.text.strip[0])
|
140
|
+
group_by = I18n.t(:eob_index_symbols_group) unless group_by.match?(/[[:alpha:]]/)
|
141
141
|
term_element['group-by'] = group_by
|
142
142
|
|
143
143
|
# Add it to our index object
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen
|
4
|
+
module Directions
|
5
|
+
module BakeNumberedNotes
|
6
|
+
def self.v1(book:, classes:)
|
7
|
+
V1.new.bake(book: book, classes: classes)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.v2(book:, classes:)
|
11
|
+
V2.new.bake(book: book, classes: classes)
|
12
|
+
end
|
13
|
+
|
14
|
+
# V3 bakes notes tied to an example immediately previous ("Try It" notes)
|
15
|
+
# Must be called AFTER BakeExercises
|
16
|
+
#
|
17
|
+
def self.v3(book:, classes:, suppress_solution: true)
|
18
|
+
V3.new.bake(book: book, classes: classes, suppress_solution: suppress_solution)
|
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
|
+
# bake problem
|
25
|
+
exercise.problem.wrap_children('div', class: 'os-problem-container')
|
26
|
+
exercise.search('[data-type="commentary"]').each(&:trash)
|
27
|
+
return unless exercise.solution
|
28
|
+
|
29
|
+
# bake solution in place
|
30
|
+
if suppress_solution
|
31
|
+
exercise.add_class('os-hasSolution')
|
32
|
+
exercise.solution.trash
|
33
|
+
else
|
34
|
+
BakeNumberedExercise.bake_solution_v1(
|
35
|
+
exercise: exercise,
|
36
|
+
number: note.first('.os-number').text.gsub(/#/, ''),
|
37
|
+
divider: divider
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::BakeNumberedNotes
|
4
|
+
|
5
|
+
class V1
|
6
|
+
def bake(book:, classes:)
|
7
|
+
classes.each do |klass|
|
8
|
+
book.chapters.notes("$.#{klass}").each do |note|
|
9
|
+
bake_note(note: note)
|
10
|
+
note.exercises.each do |exercise|
|
11
|
+
Kitchen::Directions::BakeNumberedNotes.bake_note_exercise(note: note, exercise: exercise)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def bake_note(note:)
|
18
|
+
note.wrap_children(class: 'os-note-body')
|
19
|
+
|
20
|
+
chapter_count = note.ancestor(:chapter).count_in(:book)
|
21
|
+
note_count = note.count_in(:chapter)
|
22
|
+
note.prepend(child:
|
23
|
+
<<~HTML
|
24
|
+
<h3 class="os-title">
|
25
|
+
<span class="os-title-label">#{note.autogenerated_title}</span>
|
26
|
+
<span class="os-number">#{chapter_count}.#{note_count}</span>
|
27
|
+
<span class="os-divider"> </span>
|
28
|
+
</h3>
|
29
|
+
HTML
|
30
|
+
)
|
31
|
+
|
32
|
+
return unless note['use-subtitle']
|
33
|
+
|
34
|
+
Kitchen::Directions::BakeNoteSubtitle.v1(note: note)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::BakeNumberedNotes
|
4
|
+
class V2
|
5
|
+
def bake(book:, classes:)
|
6
|
+
classes.each do |klass|
|
7
|
+
book.chapters.pages.notes("$.#{klass}").each do |note|
|
8
|
+
note.wrap_children(class: 'os-note-body')
|
9
|
+
note_count = note.count_in(:page)
|
10
|
+
note.prepend(child:
|
11
|
+
<<~HTML
|
12
|
+
<h3 class="os-title">
|
13
|
+
<span class="os-title-label">#{note.autogenerated_title}</span>
|
14
|
+
<span class="os-number">##{note_count}</span>
|
15
|
+
</h3>
|
16
|
+
HTML
|
17
|
+
)
|
18
|
+
note.exercises.each do |exercise|
|
19
|
+
Kitchen::Directions::BakeNumberedNotes.bake_note_exercise(note: note, exercise: exercise, divider: '. ')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::BakeNumberedNotes
|
4
|
+
class V3
|
5
|
+
# for the try it notes, must be called AFTER bake_exercises
|
6
|
+
def bake(book:, classes:, suppress_solution: true)
|
7
|
+
classes.each do |klass|
|
8
|
+
book.chapters.notes("$.#{klass}").each do |note|
|
9
|
+
note.wrap_children(class: 'os-note-body')
|
10
|
+
previous_example = note.previous
|
11
|
+
os_number = previous_example&.first('.os-number')&.children&.to_s
|
12
|
+
|
13
|
+
note.prepend(child:
|
14
|
+
<<~HTML
|
15
|
+
<h3 class="os-title">
|
16
|
+
<span class="os-title-label">#{note.autogenerated_title}</span>
|
17
|
+
<span class="os-number">#{os_number}</span>
|
18
|
+
</h3>
|
19
|
+
HTML
|
20
|
+
)
|
21
|
+
|
22
|
+
note.title&.trash
|
23
|
+
note.exercises.each do |exercise|
|
24
|
+
Kitchen::Directions::BakeNumberedNotes.bake_note_exercise(
|
25
|
+
note: note, exercise: exercise, divider: '. ', suppress_solution: suppress_solution
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -3,8 +3,9 @@
|
|
3
3
|
module Kitchen
|
4
4
|
module Directions
|
5
5
|
module BakeNumberedExercise
|
6
|
-
def self.v1(exercise:, number:,
|
7
|
-
V1.new.bake(exercise: exercise, number: number,
|
6
|
+
def self.v1(exercise:, number:, suppress_solution_if: false, note_suppressed_solutions: false)
|
7
|
+
V1.new.bake(exercise: exercise, number: number, suppress_solution_if: suppress_solution_if,
|
8
|
+
note_suppressed_solutions: note_suppressed_solutions)
|
8
9
|
end
|
9
10
|
|
10
11
|
def self.bake_solution_v1(exercise:, number:, divider: '. ')
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Kitchen::Directions::BakeNumberedExercise
|
4
4
|
class V1
|
5
|
-
def bake(exercise:, number:,
|
5
|
+
def bake(exercise:, number:, suppress_solution_if: false, note_suppressed_solutions: false)
|
6
6
|
problem = exercise.problem
|
7
7
|
solution = exercise.solution
|
8
8
|
|
@@ -12,9 +12,18 @@ module Kitchen::Directions::BakeNumberedExercise
|
|
12
12
|
)
|
13
13
|
problem_number = "<span class='os-number'>#{number}</span>"
|
14
14
|
|
15
|
+
suppress_solution =
|
16
|
+
case suppress_solution_if
|
17
|
+
when Symbol
|
18
|
+
number.send(suppress_solution_if)
|
19
|
+
else
|
20
|
+
suppress_solution_if
|
21
|
+
end
|
22
|
+
|
15
23
|
if solution.present?
|
16
24
|
if suppress_solution
|
17
25
|
solution.trash
|
26
|
+
exercise.add_class('os-hasSolution-trashed') if note_suppressed_solutions
|
18
27
|
else
|
19
28
|
problem_number = "<a class='os-number' href='##{exercise.id}-solution'>#{number}</a>"
|
20
29
|
bake_solution(exercise: exercise, number: number)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen
|
4
|
+
module Directions
|
5
|
+
# Bake directions for table body
|
6
|
+
#
|
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
|
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
|
23
|
+
end
|
24
|
+
|
25
|
+
table.parent.add_class('os-column-header-container') if table.column_header?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -4,22 +4,7 @@ module Kitchen::Directions::BakeNumberedTable
|
|
4
4
|
class V1
|
5
5
|
|
6
6
|
def bake(table:, number:, always_caption: false)
|
7
|
-
|
8
|
-
|
9
|
-
table_label = "#{I18n.t(:table_label)} #{number}"
|
10
|
-
table.pantry(name: :link_text).store table_label, label: table.id
|
11
|
-
|
12
|
-
if table.top_titled?
|
13
|
-
table.parent.add_class('os-top-titled-container')
|
14
|
-
table.prepend(sibling:
|
15
|
-
<<~HTML
|
16
|
-
<div class="os-table-title">#{table.title}</div>
|
17
|
-
HTML
|
18
|
-
)
|
19
|
-
table.title_row.trash
|
20
|
-
end
|
21
|
-
|
22
|
-
table.parent.add_class('os-column-header-container') if table.column_header?
|
7
|
+
Kitchen::Directions::BakeTableBody.v1(table: table, number: number)
|
23
8
|
|
24
9
|
# TODO: extra spaces added here to match legacy implementation, but probably not meaningful?
|
25
10
|
new_caption = ''
|
@@ -54,6 +39,5 @@ module Kitchen::Directions::BakeNumberedTable
|
|
54
39
|
HTML
|
55
40
|
)
|
56
41
|
end
|
57
|
-
|
58
42
|
end
|
59
43
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kitchen::Directions::BakeNumberedTable
|
4
|
+
# Difference from v1: only in the caption
|
5
|
+
# V2 caption titles are nested within an .os-caption span
|
6
|
+
class V2
|
7
|
+
|
8
|
+
def bake(table:, number:)
|
9
|
+
Kitchen::Directions::BakeTableBody.v1(table: table, number: number)
|
10
|
+
|
11
|
+
caption = ''
|
12
|
+
if table&.caption&.first("span[data-type='title']")
|
13
|
+
caption_el = table.caption
|
14
|
+
caption_el.add_class('os-caption')
|
15
|
+
caption_el.name = 'span'
|
16
|
+
caption = caption_el.cut
|
17
|
+
end
|
18
|
+
|
19
|
+
table.append(sibling:
|
20
|
+
<<~HTML
|
21
|
+
<div class="os-caption-container">
|
22
|
+
<span class="os-title-label">#{I18n.t(:table_label)} </span>
|
23
|
+
<span class="os-number">#{number}</span>
|
24
|
+
<span class="os-divider"> </span>
|
25
|
+
#{caption}
|
26
|
+
</div>
|
27
|
+
HTML
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,15 +2,16 @@
|
|
2
2
|
|
3
3
|
module Kitchen::Directions::BakePreface
|
4
4
|
class V1
|
5
|
-
def bake(book:)
|
5
|
+
def bake(book:, title_element:)
|
6
6
|
book.pages('$.preface').each do |page|
|
7
|
+
page.search('div[data-type="description"], div[data-type="abstract"]').each(&:trash)
|
7
8
|
page.titles.each do |title|
|
8
9
|
title.replace_children(with:
|
9
10
|
<<~HTML
|
10
11
|
<span data-type="" itemprop="" class="os-text">#{title.text}</span>
|
11
12
|
HTML
|
12
13
|
)
|
13
|
-
title.name =
|
14
|
+
title.name = title_element
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
data/lib/kitchen/directions/book_answer_key_container/eob_answer_key_outer_container.xhtml.erb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
<div class="os-eob os-<%= @solutions_or_solution %>-container" data-type="composite-chapter" data-uuid-key=".<%= @solutions_or_solution %>">
|
2
|
+
<h1 data-type="document-title">
|
3
|
+
<span class="os-text"><%= I18n.t(:answer_key_title) %></span>
|
4
|
+
</h1>
|
5
|
+
<div data-type="metadata" style="display: none;">
|
6
|
+
<h1 data-type="document-title" itemprop="name"><%= I18n.t(:answer_key_title) %></h1>
|
7
|
+
<%= @metadata.paste %>
|
8
|
+
</div>
|
9
|
+
</div>
|
@@ -4,10 +4,11 @@ module Kitchen::Directions::BookAnswerKeyContainer
|
|
4
4
|
class V1
|
5
5
|
renderable
|
6
6
|
|
7
|
-
def bake(book:)
|
7
|
+
def bake(book:, solutions_plural: true)
|
8
8
|
@metadata = book.metadata.children_to_keep.copy
|
9
|
-
|
10
|
-
book.body.
|
9
|
+
@solutions_or_solution = solutions_plural ? 'solutions' : 'solution'
|
10
|
+
book.body.append(child: render(file: 'eob_answer_key_outer_container.xhtml.erb'))
|
11
|
+
book.body.first("div.os-eob.os-#{@solutions_or_solution}-container")
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
<div class="os-eoc os
|
1
|
+
<div class="os-eoc os-<%= @klass %>-container" data-type="composite-chapter" data-uuid-key=".<%= @klass %>">
|
2
2
|
<h2 data-type="document-title">
|
3
|
-
<span class="os-text"><%=
|
3
|
+
<span class="os-text"><%= @title %></span>
|
4
4
|
</h2>
|
5
5
|
<div data-type="metadata" style="display: none;">
|
6
|
-
<h1 data-type="document-title" itemprop="name"><%=
|
6
|
+
<h1 data-type="document-title" itemprop="name"><%= @title %></h1>
|
7
7
|
<%= @metadata.paste %>
|
8
8
|
</div>
|
9
9
|
</div>
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Kitchen
|
4
4
|
module Directions
|
5
5
|
module ChapterReviewContainer
|
6
|
-
def self.v1(chapter:, metadata_source:)
|
7
|
-
V1.new.bake(chapter: chapter, metadata_source: metadata_source)
|
6
|
+
def self.v1(chapter:, metadata_source:, klass: 'chapter-review')
|
7
|
+
V1.new.bake(chapter: chapter, metadata_source: metadata_source, klass: klass)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -4,10 +4,12 @@ module Kitchen::Directions::ChapterReviewContainer
|
|
4
4
|
class V1
|
5
5
|
renderable
|
6
6
|
|
7
|
-
def bake(chapter:, metadata_source:)
|
7
|
+
def bake(chapter:, metadata_source:, klass: 'chapter-review')
|
8
8
|
@metadata = metadata_source.children_to_keep.copy
|
9
|
+
@klass = klass
|
10
|
+
@title = I18n.t(:"eoc.#{klass}")
|
9
11
|
chapter.append(child: render(file: 'chapter_review.xhtml.erb'))
|
10
|
-
chapter.
|
12
|
+
chapter.element_children[-1]
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
@@ -15,6 +15,19 @@ module Kitchen
|
|
15
15
|
</a>
|
16
16
|
HTML
|
17
17
|
end
|
18
|
+
|
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>
|
29
|
+
HTML
|
30
|
+
end
|
18
31
|
end
|
19
32
|
end
|
20
33
|
end
|