openstax_kitchen 3.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/CHANGELOG.md +64 -0
- data/Gemfile.lock +20 -14
- data/README.md +16 -0
- data/codecov.yaml +1 -0
- data/docker/ci +0 -1
- data/lib/kitchen/book_document.rb +1 -1
- data/lib/kitchen/book_element.rb +16 -2
- data/lib/kitchen/chapter_element.rb +10 -13
- data/lib/kitchen/chapter_element_enumerator.rb +1 -1
- data/lib/kitchen/composite_chapter_element.rb +7 -11
- data/lib/kitchen/composite_chapter_element_enumerator.rb +21 -0
- data/lib/kitchen/composite_page_element.rb +15 -10
- data/lib/kitchen/composite_page_element_enumerator.rb +1 -1
- data/lib/kitchen/config.rb +14 -0
- data/lib/kitchen/directions/bake_chapter_glossary/main.rb +18 -0
- data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +30 -0
- data/lib/kitchen/directions/bake_chapter_introductions.rb +1 -1
- data/lib/kitchen/directions/bake_chapter_key_concepts/main.rb +7 -2
- data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +12 -7
- data/lib/kitchen/directions/bake_chapter_key_equations.rb +26 -21
- data/lib/kitchen/directions/bake_chapter_references/main.rb +16 -0
- data/lib/kitchen/directions/bake_chapter_references/v1.rb +35 -0
- data/lib/kitchen/directions/bake_chapter_summary.rb +48 -42
- data/lib/kitchen/directions/bake_composite_chapters.rb +1 -1
- data/lib/kitchen/directions/bake_composite_pages.rb +1 -1
- data/lib/kitchen/directions/bake_equations.rb +14 -4
- data/lib/kitchen/directions/bake_example.rb +5 -1
- data/lib/kitchen/directions/bake_figure.rb +1 -1
- data/lib/kitchen/directions/bake_first_elements.rb +22 -0
- data/lib/kitchen/directions/bake_footnotes/v1.rb +2 -1
- data/lib/kitchen/directions/bake_free_response/free_response.xhtml.erb +10 -0
- data/lib/kitchen/directions/bake_free_response/main.rb +11 -0
- data/lib/kitchen/directions/bake_free_response/v1.rb +29 -0
- data/lib/kitchen/directions/bake_further_research.rb +59 -0
- data/lib/kitchen/directions/bake_index/v1.rb +36 -26
- data/lib/kitchen/directions/bake_link_placeholders.rb +1 -1
- data/lib/kitchen/directions/bake_notes/bake_note_subtitle.rb +4 -0
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes.rb +9 -21
- data/lib/kitchen/directions/bake_numbered_exercise/main.rb +6 -2
- data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +25 -12
- data/lib/kitchen/directions/bake_numbered_table/v1.rb +1 -8
- data/lib/kitchen/directions/bake_page_abstracts.rb +1 -1
- data/lib/kitchen/directions/bake_references/main.rb +16 -0
- data/lib/kitchen/directions/bake_references/v1.rb +48 -0
- data/lib/kitchen/directions/bake_suggested_reading.rb +5 -0
- data/lib/kitchen/directions/bake_toc.rb +4 -2
- data/lib/kitchen/directions/{bake_book_answer_key → book_answer_key_container}/eob_solutions_container.xhtml.erb +0 -0
- data/lib/kitchen/directions/{bake_book_answer_key → book_answer_key_container}/main.rb +1 -1
- data/lib/kitchen/directions/{bake_book_answer_key → book_answer_key_container}/v1.rb +2 -2
- data/lib/kitchen/directions/{bake_chapter_review → chapter_review_container}/chapter_review.xhtml.erb +0 -0
- data/lib/kitchen/directions/{bake_chapter_review → chapter_review_container}/main.rb +1 -1
- data/lib/kitchen/directions/{bake_chapter_review → chapter_review_container}/v1.rb +2 -2
- data/lib/kitchen/directions/eoc_section_title_link_snippet.rb +1 -1
- data/lib/kitchen/directions/move_exercises_to_eoc/main.rb +27 -0
- data/lib/kitchen/directions/{bake_chapter_review_exercises → move_exercises_to_eoc}/v1.rb +8 -10
- data/lib/kitchen/directions/{bake_chapter_review_exercises → move_exercises_to_eoc}/v2.rb +8 -9
- data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/main.rb +1 -1
- data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/american_government.rb +19 -0
- data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/strategies/calculus.rb +1 -1
- data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/strategies/uphysics.rb +7 -5
- data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/v1.rb +3 -1
- data/lib/kitchen/document.rb +20 -42
- data/lib/kitchen/element.rb +9 -3
- data/lib/kitchen/element_base.rb +93 -21
- data/lib/kitchen/element_enumerator_base.rb +33 -2
- data/lib/kitchen/element_enumerator_factory.rb +28 -12
- data/lib/kitchen/element_factory.rb +3 -3
- data/lib/kitchen/example_element.rb +8 -11
- data/lib/kitchen/example_element_enumerator.rb +1 -1
- data/lib/kitchen/exercise_element.rb +7 -10
- data/lib/kitchen/exercise_element_enumerator.rb +1 -1
- data/lib/kitchen/figure_element.rb +8 -11
- data/lib/kitchen/figure_element_enumerator.rb +1 -1
- data/lib/kitchen/id_tracker.rb +68 -0
- data/lib/kitchen/metadata_element.rb +8 -2
- data/lib/kitchen/metadata_element_enumerator.rb +1 -1
- data/lib/kitchen/note_element.rb +8 -11
- data/lib/kitchen/note_element_enumerator.rb +1 -1
- data/lib/kitchen/oven.rb +5 -1
- data/lib/kitchen/page_element.rb +25 -9
- data/lib/kitchen/page_element_enumerator.rb +1 -1
- data/lib/kitchen/patches/i18n.rb +34 -0
- data/lib/kitchen/patches/nokogiri.rb +55 -0
- data/lib/kitchen/patches/nokogiri_profiling.rb +60 -0
- data/lib/kitchen/reference_element.rb +27 -0
- data/lib/kitchen/references_element_enumerator.rb +20 -0
- data/lib/kitchen/search_query.rb +31 -3
- data/lib/kitchen/selector.rb +25 -0
- data/lib/kitchen/selectors/base.rb +39 -0
- data/lib/kitchen/selectors/standard_1.rb +13 -0
- data/lib/kitchen/table_element.rb +8 -11
- data/lib/kitchen/table_element_enumerator.rb +1 -1
- data/lib/kitchen/templates/eob_section_title_template.xhtml.erb +10 -0
- data/lib/kitchen/templates/eoc_section_title_template.xhtml.erb +10 -0
- data/lib/kitchen/term_element.rb +5 -8
- data/lib/kitchen/term_element_enumerator.rb +1 -1
- data/lib/kitchen/unit_element.rb +13 -7
- data/lib/kitchen/unit_element_enumerator.rb +1 -1
- data/lib/kitchen/version.rb +1 -1
- data/lib/locales/en.yml +3 -0
- data/lib/locales/es.yml +32 -0
- data/lib/openstax_kitchen.rb +2 -5
- data/openstax_kitchen.gemspec +1 -0
- metadata +51 -23
- data/lib/kitchen/directions/bake_chapter_glossary.rb +0 -39
- data/lib/kitchen/directions/bake_chapter_key_concepts/key_concepts.xhtml.erb +0 -16
- data/lib/kitchen/directions/bake_chapter_review_exercises/main.rb +0 -15
- data/lib/kitchen/directions/bake_chapter_review_exercises/review_exercises.xhtml.erb +0 -10
- data/lib/kitchen/directions/bake_exercises/main.rb +0 -12
- data/lib/kitchen/directions/bake_exercises/v1.rb +0 -169
- data/lib/kitchen/directions/bake_notes/bake_notes.rb +0 -48
- data/lib/kitchen/directions/bake_problem_first_elements.rb +0 -16
- data/lib/kitchen/transliterations.rb +0 -21
@@ -1,10 +0,0 @@
|
|
1
|
-
<div class="os-eoc os-<%=@klass%>-container" data-type="composite-page" data-uuid-key=".<%=@klass%>">
|
2
|
-
<h3 data-type="document-title">
|
3
|
-
<span class="os-text"><%= @title %></span>
|
4
|
-
</h3>
|
5
|
-
<div data-type="metadata" style="display: none;">
|
6
|
-
<h1 data-type="document-title" itemprop="name"><%= I18n.t(:eoc_exercises_title) %></h1>
|
7
|
-
<%= @metadata.paste %>
|
8
|
-
</div>
|
9
|
-
<%= @content %>
|
10
|
-
</div>
|
@@ -1,169 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Kitchen::Directions::BakeExercises
|
4
|
-
class V1
|
5
|
-
renderable
|
6
|
-
def bake(book:)
|
7
|
-
metadata_elements = book.metadata.children_to_keep.copy
|
8
|
-
|
9
|
-
solutions_clipboards = []
|
10
|
-
|
11
|
-
book.chapters.each do |chapter|
|
12
|
-
exercise_clipboard = Kitchen::Clipboard.new
|
13
|
-
solution_clipboard = Kitchen::Clipboard.new
|
14
|
-
solutions_clipboards.push(solution_clipboard)
|
15
|
-
|
16
|
-
chapter.non_introduction_pages.each do |page|
|
17
|
-
exercise_section = page.exercises
|
18
|
-
exercise_section.titles.first&.trash
|
19
|
-
|
20
|
-
bake_exercise_section_title(
|
21
|
-
exercise_section: exercise_section, page: page, chapter: chapter)
|
22
|
-
|
23
|
-
exercise_section.exercises.each do |exercise|
|
24
|
-
exercise.document.pantry(name: :link_text).store(
|
25
|
-
"#{I18n.t(:exercise_label)} #{chapter.count_in(:book)}.#{exercise.count_in(:chapter)}",
|
26
|
-
label: exercise.id
|
27
|
-
)
|
28
|
-
bake_exercise_in_place(exercise: exercise)
|
29
|
-
exercise.solution&.cut(to: solution_clipboard)
|
30
|
-
end
|
31
|
-
|
32
|
-
exercise_section.cut(to: exercise_clipboard)
|
33
|
-
end
|
34
|
-
|
35
|
-
next if exercise_clipboard.none?
|
36
|
-
|
37
|
-
chapter.append(child:
|
38
|
-
<<~HTML
|
39
|
-
<div class="os-eoc os-exercises-container" data-type="composite-page" data-uuid-key=".exercises">
|
40
|
-
<h2 data-type="document-title">
|
41
|
-
<span class="os-text">#{I18n.t(:eoc_exercises_title)}</span>
|
42
|
-
</h2>
|
43
|
-
<div data-type="metadata" style="display: none;">
|
44
|
-
<h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_exercises_title)}</h1>
|
45
|
-
#{metadata_elements.paste}
|
46
|
-
</div>
|
47
|
-
#{exercise_clipboard.paste}
|
48
|
-
</div>
|
49
|
-
HTML
|
50
|
-
)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Store a paste here to use at end so that uniquifyied IDs match legacy baking
|
54
|
-
eob_metadata = metadata_elements.paste
|
55
|
-
solutions = solutions_clipboards.map.with_index do |solution_clipboard, index|
|
56
|
-
<<~HTML
|
57
|
-
<div class="os-eob os-solution-container" data-type="composite-page" data-uuid-key=".solution#{index + 1}">
|
58
|
-
<h2 data-type="document-title">
|
59
|
-
<span class="os-text">#{I18n.t(:chapter)} #{index + 1}</span>
|
60
|
-
</h2>
|
61
|
-
<div data-type="metadata" style="display: none;">
|
62
|
-
<h1 data-type="document-title" itemprop="name">#{I18n.t(:chapter)} #{index + 1}</h1>
|
63
|
-
#{metadata_elements.paste}
|
64
|
-
</div>
|
65
|
-
#{solution_clipboard.paste}
|
66
|
-
</div>
|
67
|
-
HTML
|
68
|
-
end
|
69
|
-
|
70
|
-
return if solutions.none?
|
71
|
-
|
72
|
-
book.body.append(child:
|
73
|
-
<<~HTML
|
74
|
-
<div class="os-eob os-solution-container" data-type="composite-chapter" data-uuid-key=".solution">
|
75
|
-
<h1 data-type="document-title" id="composite-chapter-1">
|
76
|
-
<span class="os-text">#{I18n.t(:eoc_answer_key_title)}</span>
|
77
|
-
</h1>
|
78
|
-
<div data-type="metadata" style="display: none;">
|
79
|
-
<h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_answer_key_title)}</h1>
|
80
|
-
#{eob_metadata}
|
81
|
-
</div>
|
82
|
-
#{solutions.join("\n")}
|
83
|
-
</div>
|
84
|
-
HTML
|
85
|
-
)
|
86
|
-
end
|
87
|
-
|
88
|
-
def bake_exercise_section_title(exercise_section:, chapter:, page:)
|
89
|
-
exercise_section_title = page.title.copy
|
90
|
-
exercise_section_title.name = 'h3'
|
91
|
-
exercise_section_title.replace_children(with: <<~HTML
|
92
|
-
<span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
|
93
|
-
<span class="os-divider"> </span>
|
94
|
-
<span class="os-text" data-type="" itemprop="">#{exercise_section_title.children}</span>
|
95
|
-
HTML
|
96
|
-
)
|
97
|
-
exercise_section.prepend(child:
|
98
|
-
<<~HTML
|
99
|
-
<a href="##{page.title.id}">
|
100
|
-
#{exercise_section_title.paste}
|
101
|
-
</a>
|
102
|
-
HTML
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
def bake_exercise_in_place(exercise:)
|
107
|
-
# Bake an exercise in place going from:
|
108
|
-
#
|
109
|
-
# <div data-type="exercise" id="exerciseId">
|
110
|
-
# <div data-type="problem" id="problemId">
|
111
|
-
# Problem Content
|
112
|
-
# </div>
|
113
|
-
# <div data-type="solution" id="solutionId">
|
114
|
-
# Solution Content
|
115
|
-
# </div>
|
116
|
-
# </div>
|
117
|
-
#
|
118
|
-
# to
|
119
|
-
#
|
120
|
-
# <div data-type="exercise" id="exerciseId" class="os-hasSolution">
|
121
|
-
# <div data-type="problem" id="problemId">
|
122
|
-
# <a class="os-number" href="#exerciseId-solution">1</a>
|
123
|
-
# <span class="os-divider">. </span>
|
124
|
-
# <div class="os-problem-container ">
|
125
|
-
# Problem Content
|
126
|
-
# </div>
|
127
|
-
# </div>
|
128
|
-
# <div data-type="solution" id="exerciseId-solution">
|
129
|
-
# <a class="os-number" href="#exerciseId">1</a>
|
130
|
-
# <span class="os-divider">. </span>
|
131
|
-
# <div class="os-solution-container ">
|
132
|
-
# Solution Content
|
133
|
-
# </div>
|
134
|
-
# </div>
|
135
|
-
# </div>
|
136
|
-
#
|
137
|
-
# If there is no solution, don't add the 'os-hasSolution' class and don't
|
138
|
-
# link the number.
|
139
|
-
|
140
|
-
problem = exercise.problem
|
141
|
-
solution = exercise.solution
|
142
|
-
count_in = exercise.count_in(:chapter)
|
143
|
-
problem_number = "<span class='os-number'>#{count_in}</span>"
|
144
|
-
|
145
|
-
if solution.present?
|
146
|
-
solution.id = "#{exercise.id}-solution"
|
147
|
-
|
148
|
-
exercise.add_class('os-hasSolution')
|
149
|
-
problem_number = "<a href='##{solution.id}' class='os-number'>#{count_in}</a>"
|
150
|
-
|
151
|
-
solution.replace_children(with:
|
152
|
-
<<~HTML
|
153
|
-
<a class="os-number" href="##{exercise.id}">#{count_in}</a>
|
154
|
-
<span class="os-divider">. </span>
|
155
|
-
<div class="os-solution-container ">#{solution.children}</div>
|
156
|
-
HTML
|
157
|
-
)
|
158
|
-
end
|
159
|
-
|
160
|
-
problem.replace_children(with:
|
161
|
-
<<~HTML
|
162
|
-
#{problem_number}
|
163
|
-
<span class="os-divider">. </span>
|
164
|
-
<div class="os-problem-container ">#{problem.children}</div>
|
165
|
-
HTML
|
166
|
-
)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Kitchen
|
4
|
-
module Directions
|
5
|
-
module BakeNotes
|
6
|
-
def self.v1(book:)
|
7
|
-
warn 'WARNING! deprecated direction used: BakeNotes'
|
8
|
-
|
9
|
-
book.notes('$:not(.checkpoint):not(.theorem)').each do |note|
|
10
|
-
title = note.title&.cut
|
11
|
-
|
12
|
-
note.wrap_children(class: 'os-note-body')
|
13
|
-
|
14
|
-
if title
|
15
|
-
if note.indicates_autogenerated_title?
|
16
|
-
note.prepend(child:
|
17
|
-
<<~HTML
|
18
|
-
<h3 class="os-title" data-type="title">
|
19
|
-
<span class="os-title-label">#{note.autogenerated_title}</span>
|
20
|
-
</h3>
|
21
|
-
HTML
|
22
|
-
)
|
23
|
-
|
24
|
-
title.name = 'h4'
|
25
|
-
title.add_class('os-subtitle')
|
26
|
-
title.wrap_children('span', class: 'os-subtitle-label')
|
27
|
-
note.first!('.os-note-body').prepend(child: title.raw)
|
28
|
-
else
|
29
|
-
title.name = 'h3'
|
30
|
-
title.add_class('os-title')
|
31
|
-
title.wrap_children('span', data_type: '', id: title.id, class: 'os-title-label')
|
32
|
-
title.remove_attribute('id')
|
33
|
-
note.prepend(child: title.raw)
|
34
|
-
end
|
35
|
-
else
|
36
|
-
note.prepend(child:
|
37
|
-
<<~HTML
|
38
|
-
<h3 class="os-title" data-type="title">
|
39
|
-
<span class="os-title-label">#{note.autogenerated_title}</span>
|
40
|
-
</h3>
|
41
|
-
HTML
|
42
|
-
)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Kitchen
|
4
|
-
module Directions
|
5
|
-
module BakeProblemFirstElements
|
6
|
-
def self.v1(within:, selectors:)
|
7
|
-
selectors.each do |selector|
|
8
|
-
within.search(".os-problem-container > #{selector}:first-child").each do |problem|
|
9
|
-
problem.add_class('first-element')
|
10
|
-
problem.parent.add_class('has-first-element')
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Kitchen
|
4
|
-
# These are added to every translation locale, including the `test` locale
|
5
|
-
# set by `stub_locales`. When we sort strings with accent marks, we use
|
6
|
-
# `ActiveSupport::Inflector.transliterate` to ensure that the sorting is
|
7
|
-
# sensible. This method does not know about Greek characters by default so
|
8
|
-
# we teach it about them by adding the rules below to the i18n configuration.
|
9
|
-
#
|
10
|
-
TRANSLITERATIONS = {
|
11
|
-
i18n: {
|
12
|
-
transliterate: {
|
13
|
-
rule: {
|
14
|
-
σ: 'σ',
|
15
|
-
Δ: 'Δ',
|
16
|
-
π: 'π'
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|
20
|
-
}.freeze
|
21
|
-
end
|