openstax_kitchen 11.1.0 → 12.2.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 +42 -0
- data/Gemfile.lock +2 -2
- data/lib/kitchen/chapter_element.rb +7 -0
- data/lib/kitchen/directions/bake_accessibility_fixes.rb +11 -0
- data/lib/kitchen/directions/bake_autotitled_exercise/main.rb +11 -0
- data/lib/kitchen/directions/bake_autotitled_exercise/v1.rb +28 -0
- data/lib/kitchen/directions/bake_chapter_introductions/bake_chapter_objectives.rb +2 -0
- data/lib/kitchen/directions/bake_chapter_introductions/v1.rb +8 -48
- data/lib/kitchen/directions/bake_chapter_references/v1.rb +2 -0
- data/lib/kitchen/directions/bake_eoc_section_content/remove_section_title.rb +2 -2
- data/lib/kitchen/directions/bake_example.rb +3 -3
- data/lib/kitchen/directions/bake_figure.rb +3 -2
- data/lib/kitchen/directions/bake_footnotes/v1.rb +5 -1
- data/lib/kitchen/directions/bake_free_response/v1.rb +3 -1
- data/lib/kitchen/directions/bake_injected_exercise/add_injected_exercise_id.rb +16 -0
- data/lib/kitchen/directions/{bake_injected_exercise_question.rb → bake_injected_exercise/bake_injected_exercise_question.rb} +0 -0
- data/lib/kitchen/directions/{bake_page_abstracts.rb → bake_learning_objectives.rb} +10 -5
- data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +36 -4
- data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +5 -0
- data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +3 -0
- data/lib/kitchen/directions/bake_numbered_table/v1.rb +2 -0
- data/lib/kitchen/directions/bake_numbered_table/v2.rb +2 -0
- data/lib/kitchen/directions/bake_references/main.rb +3 -2
- data/lib/kitchen/directions/bake_references/v1.rb +8 -3
- data/lib/kitchen/directions/bake_stepwise.rb +1 -1
- data/lib/kitchen/directions/bake_unnumbered_tables.rb +1 -0
- data/lib/kitchen/directions/move_solutions_to_answer_key/v1.rb +3 -1
- data/lib/kitchen/element_base.rb +10 -18
- data/lib/kitchen/element_enumerator_base.rb +17 -0
- data/lib/kitchen/example_element.rb +2 -1
- data/lib/kitchen/exercise_element.rb +42 -0
- data/lib/kitchen/figure_element.rb +1 -1
- data/lib/kitchen/metadata_element.rb +6 -1
- data/lib/kitchen/note_element.rb +19 -5
- data/lib/kitchen/table_element.rb +8 -0
- data/lib/kitchen/version.rb +1 -1
- data/lib/locales/en.yml +1 -0
- metadata +8 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f36305ee23acfe22fc13a9c06ee76f69243f1cd2cba33fe86c28c8c90b5eb36d
|
|
4
|
+
data.tar.gz: fd501ef342ff2c7334455cc214139581dadf1619fde7841a29650b4fc10acd79
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e3b939d8a9851db4940213aae3350f720369eb794b8551627d2a44565af36aeda5ad701b62c2c1ec98fb7dcfabafa8bd2e4531642bf40dd777a635c0117560b6
|
|
7
|
+
data.tar.gz: 5ec8d3e59faa619a3b23a84ce74514c96b6d360dc1b46d233cd1566b63815a5a7edaa73980f102b4c6656c603c43ea349fcc2eac99149cbafb8fa91d8f0e2fdc
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [12.2.0] - 2021-10-1
|
|
10
|
+
|
|
11
|
+
* Add `context_lead_text` to translations (minor)
|
|
12
|
+
* Make `ElementBase#search_with` callable from an `ElementEnumerator` (minor)
|
|
13
|
+
* Support top-titled tables in `BakeUnnumberedTables` (minor)
|
|
14
|
+
* Stop `NoteElement#title` from breaking for empty notes (patch)
|
|
15
|
+
* Add text heavy tables to `BakeTableBody` (minor)
|
|
16
|
+
* Modify `BakeAutotitledNotes` to bake unnumbered exercises with solution (minor)
|
|
17
|
+
* Create `AddInjectedExerciseId` to separate creating ids from `BakeInjectedExerciseQuestion` (minor)
|
|
18
|
+
* Rework `AddInjectedExerciseId` to use loop inside module (minor)
|
|
19
|
+
|
|
20
|
+
## [12.1.0] - 2021-09-24
|
|
21
|
+
|
|
22
|
+
* Fix `BakeExample#titles_to_rename` to exclude exercise titles (patch)
|
|
23
|
+
* Modify `BakeFigure` to bake unnumbered figures with caption (minor)
|
|
24
|
+
* Fix `NoteElement#title` to be more specific about finding the title (patch)
|
|
25
|
+
* Adds `data-type="slug"` to `metadata_lement` `children_to_keep` method, updates spec helper `metadata_element` and related spec files(minor)
|
|
26
|
+
|
|
27
|
+
## [12.0.0] - 2021-09-21
|
|
28
|
+
|
|
29
|
+
* Fixes `BakeStepwise` to skip nested lists (patch)
|
|
30
|
+
* Adds an optional selector to `RemoveSectionTitles` (minor)
|
|
31
|
+
* Patches `BakeFreeResponse` to only delete the first h3, not all h3s (patch)
|
|
32
|
+
* Lets `BakeExample` not count titles in lists as commentary titles (minor)
|
|
33
|
+
* Renames `BakePageAbstracts` to `BakeLearningObjectives` and adds optional parameter for titles in `v2` (major)
|
|
34
|
+
* Gets rid of extraneous titles in `BakeAutoTitledNotes` when subtitles are off (minor)
|
|
35
|
+
* Adds `BakeAutotitledExercise` direction and the option to `bake_unclassified_exercises` within `BakeAutotitledNotes`
|
|
36
|
+
* Adds optional numbering for `BakeReferences.v1` (minor)
|
|
37
|
+
* Patches`BakeNumberedNotes.v3` to suppress solutions outside examples when suppress_solutions is true (minor)
|
|
38
|
+
|
|
39
|
+
## [11.2.0] - 2021-09-10
|
|
40
|
+
|
|
41
|
+
* Adds `BakeAccessibilityFixes` direction for (minor)
|
|
42
|
+
* Remove deprecation warning from `BakeChapterIntroductions.v1` and adapted to be used like `.v2` (minor)
|
|
43
|
+
* Small class fix for `BakeFootnotes.v1` (patch)
|
|
44
|
+
* Fix `BakeNumberedNotes` to find related example better (minor)
|
|
45
|
+
* Small fix for parameter in `bake_note` definition (minor)
|
|
46
|
+
* Small fixes to return when no elements are found and not add an empty wrapper in `BakeChapterReferences` and
|
|
47
|
+
`BakeFreeResponse` (minor)
|
|
48
|
+
* Adding class `os-timeline-table-container` to numbered tables when required (minor)
|
|
49
|
+
* Fix `BakeExample` to catch the multiple solutions to one exercise (patch)
|
|
50
|
+
|
|
9
51
|
## [11.1.0] - 2021-08-30
|
|
10
52
|
|
|
11
53
|
* Update injected questions to synthesize ids during baking (minor)
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
openstax_kitchen (
|
|
4
|
+
openstax_kitchen (12.2.0)
|
|
5
5
|
activesupport
|
|
6
6
|
i18n
|
|
7
7
|
nokogiri
|
|
@@ -11,7 +11,7 @@ PATH
|
|
|
11
11
|
GEM
|
|
12
12
|
remote: https://rubygems.org/
|
|
13
13
|
specs:
|
|
14
|
-
activesupport (6.1.4)
|
|
14
|
+
activesupport (6.1.4.1)
|
|
15
15
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
16
16
|
i18n (>= 1.6, < 2)
|
|
17
17
|
minitest (>= 5.1)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kitchen::Directions::BakeAutotitledExercise
|
|
4
|
+
class V1
|
|
5
|
+
def bake(exercise:, number:)
|
|
6
|
+
exercise.add_class('unnumbered') unless number
|
|
7
|
+
|
|
8
|
+
# bake problem
|
|
9
|
+
exercise.problem.wrap_children('div', class: 'os-problem-container')
|
|
10
|
+
exercise.problem.prepend(child:
|
|
11
|
+
<<~HTML
|
|
12
|
+
<h4 class="exercise-title" data-type="title">#{exercise.autogenerated_title}</h4>
|
|
13
|
+
HTML
|
|
14
|
+
)
|
|
15
|
+
return unless exercise.solution
|
|
16
|
+
|
|
17
|
+
# bake solution in place
|
|
18
|
+
exercise.solution.wrap_children('div', class: 'os-solution-container')
|
|
19
|
+
exercise.solution.prepend(child:
|
|
20
|
+
<<~HTML
|
|
21
|
+
<h4 class="solution-title" data-type="title">
|
|
22
|
+
<span class="os-text">#{I18n.t(:"exercises.solution")}</span>
|
|
23
|
+
</h4>
|
|
24
|
+
HTML
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -18,6 +18,8 @@ module Kitchen::Directions::BakeChapterIntroductions
|
|
|
18
18
|
def bake_as_note(chapter:)
|
|
19
19
|
chapter_objectives_note = chapter.notes('$.chapter-objectives').first
|
|
20
20
|
|
|
21
|
+
return unless chapter_objectives_note.present?
|
|
22
|
+
|
|
21
23
|
# trash existing title
|
|
22
24
|
chapter_objectives_note.titles.first&.trash
|
|
23
25
|
Kitchen::Directions::BakeAutotitledNotes.v1(
|
|
@@ -3,54 +3,14 @@
|
|
|
3
3
|
module Kitchen::Directions::BakeChapterIntroductions
|
|
4
4
|
class V1
|
|
5
5
|
def bake(book:)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
title = introduction_page.title.cut
|
|
16
|
-
title.name = 'h2'
|
|
17
|
-
Kitchen::Directions::MoveTitleTextIntoSpan.v1(title: title)
|
|
18
|
-
|
|
19
|
-
intro_content = introduction_page.search(
|
|
20
|
-
"> :not([data-type='metadata']):not(.splash):not(.has-splash)"
|
|
21
|
-
).cut
|
|
22
|
-
|
|
23
|
-
chapter_objectives_html = chapter.non_introduction_pages.map do |page|
|
|
24
|
-
<<~HTML
|
|
25
|
-
<div class="os-chapter-objective">
|
|
26
|
-
<a class="os-chapter-objective" href="##{page.title[:id]}">
|
|
27
|
-
<span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
|
|
28
|
-
<span class="os-divider"> </span>
|
|
29
|
-
<span data-type="" itemprop="" class="os-text">#{page.title.children[0].text}</span>
|
|
30
|
-
</a>
|
|
31
|
-
</div>
|
|
32
|
-
HTML
|
|
33
|
-
end.join('')
|
|
34
|
-
|
|
35
|
-
chapter_outline =
|
|
36
|
-
Kitchen::Directions::BakeChapterIntroductions.bake_chapter_outline(
|
|
37
|
-
chapter_objectives_html: chapter_objectives_html
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
introduction_page.append(child:
|
|
41
|
-
<<~HTML
|
|
42
|
-
<div class="intro-body">
|
|
43
|
-
#{chapter_outline}
|
|
44
|
-
<div class="intro-text">
|
|
45
|
-
#{title.paste}
|
|
46
|
-
#{intro_content.paste}
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
HTML
|
|
50
|
-
)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
Kitchen::Directions::BakeChapterIntroductions.v1_update_selectors(book)
|
|
6
|
+
Kitchen::Directions::BakeChapterIntroductions.v2(
|
|
7
|
+
book: book,
|
|
8
|
+
strategy_options: {
|
|
9
|
+
strategy: :add_objectives,
|
|
10
|
+
bake_chapter_outline: true,
|
|
11
|
+
introduction_order: :v1
|
|
12
|
+
}
|
|
13
|
+
)
|
|
54
14
|
end
|
|
55
15
|
end
|
|
56
16
|
end
|
|
@@ -30,9 +30,9 @@ module Kitchen
|
|
|
30
30
|
problem.wrap_children(class: 'os-problem-container')
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
exercise.solutions.each do |solution|
|
|
34
34
|
solution_number = if numbered_solutions
|
|
35
|
-
"<span class=\"os-number\">#{
|
|
35
|
+
"<span class=\"os-number\">#{solution.count_in(:example)}</span>"
|
|
36
36
|
else
|
|
37
37
|
''
|
|
38
38
|
end
|
|
@@ -53,7 +53,7 @@ module Kitchen
|
|
|
53
53
|
next unless commentary.present?
|
|
54
54
|
|
|
55
55
|
commentary_title = commentary.titles.first
|
|
56
|
-
next unless commentary_title.present?
|
|
56
|
+
next unless commentary_title.present? && commentary_title.parent['data-type'] != 'list'
|
|
57
57
|
|
|
58
58
|
commentary_title.name = 'h4'
|
|
59
59
|
commentary_title['data-type'] = 'commentary-title'
|
|
@@ -4,10 +4,11 @@ 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')
|
|
7
|
+
return if figure.has_class?('unnumbered') && !figure.has_class?('splash') && !figure.caption
|
|
8
8
|
|
|
9
9
|
figure.wrap(%(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
if figure.has_class?('unnumbered') && (figure.caption || figure.has_class?('splash'))
|
|
11
12
|
caption = figure.caption&.cut
|
|
12
13
|
figure.append(sibling:
|
|
13
14
|
<<~HTML
|
|
@@ -28,7 +28,11 @@ module Kitchen::Directions::BakeFootnotes
|
|
|
28
28
|
anchor.replace_children(with: footnote_number)
|
|
29
29
|
aside_id = anchor[:href][1..-1]
|
|
30
30
|
aside_id_to_footnote_number[aside_id] = footnote_number
|
|
31
|
-
|
|
31
|
+
if anchor.parent.name == 'p'
|
|
32
|
+
anchor.parent.add_class('has-noteref')
|
|
33
|
+
elsif anchor.parent.name == 'em' && anchor.parent.parent.name == 'p'
|
|
34
|
+
anchor.parent.parent.add_class('has-noteref')
|
|
35
|
+
end
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
container.search('aside').each do |aside|
|
|
@@ -12,7 +12,7 @@ module Kitchen::Directions::BakeFreeResponse
|
|
|
12
12
|
free_response_questions = page.free_response
|
|
13
13
|
next if free_response_questions.none?
|
|
14
14
|
|
|
15
|
-
free_response_questions.search('h3')
|
|
15
|
+
free_response_questions.search('h3')&.first&.trash
|
|
16
16
|
title = Kitchen::Directions::EocSectionTitleLinkSnippet.v1(page: page)
|
|
17
17
|
free_response_questions.each do |free_response_question|
|
|
18
18
|
free_response_question.prepend(child: title)
|
|
@@ -20,6 +20,8 @@ module Kitchen::Directions::BakeFreeResponse
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
return if @free_response_clipboard.none?
|
|
24
|
+
|
|
23
25
|
append_to_element = append_to || chapter
|
|
24
26
|
@title_tag = append_to ? 'h3' : 'h2'
|
|
25
27
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kitchen
|
|
4
|
+
module Directions
|
|
5
|
+
# Ids should be added before exercises are moved to EOC,
|
|
6
|
+
# since they're using part of the ancestor page id.
|
|
7
|
+
#
|
|
8
|
+
# In some books exercises are numbered after moving.
|
|
9
|
+
# That's why this step has to be separated from BakeInjectedExerciseQuestion
|
|
10
|
+
module AddInjectedExerciseId
|
|
11
|
+
def self.v1(book:)
|
|
12
|
+
book.pages.injected_questions.each(&:id)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
File without changes
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
module Kitchen
|
|
4
4
|
module Directions
|
|
5
|
-
|
|
6
|
-
module BakePageAbstracts
|
|
5
|
+
module BakeLearningObjectives
|
|
7
6
|
def self.v1(chapter:)
|
|
8
7
|
chapter.abstracts.each do |abstract|
|
|
9
8
|
abstract.prepend(child: "<h3 data-type='title'>#{I18n.t(:learning_objectives)}</h3>")
|
|
10
9
|
end
|
|
11
10
|
end
|
|
12
11
|
|
|
13
|
-
def self.v2(chapter:)
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
def self.v2(chapter:, add_title: true)
|
|
13
|
+
learning_objectives =
|
|
14
|
+
chapter.abstracts.any? ? chapter.abstracts : chapter.learning_objectives
|
|
15
|
+
|
|
16
|
+
learning_objectives.each do |abstract|
|
|
17
|
+
if add_title
|
|
18
|
+
abstract.prepend(child: "<h3 data-type='title'>#{I18n.t(:learning_objectives)}</h3>")
|
|
19
|
+
end
|
|
20
|
+
|
|
16
21
|
ul = abstract.first!('ul')
|
|
17
22
|
ul.add_class('os-abstract')
|
|
18
23
|
ul.search('li').each_with_index do |li, index|
|
|
@@ -3,19 +3,24 @@
|
|
|
3
3
|
module Kitchen
|
|
4
4
|
module Directions
|
|
5
5
|
module BakeAutotitledNotes
|
|
6
|
-
def self.v1(book:, classes:, bake_subtitle: true, cases: false)
|
|
6
|
+
def self.v1(book:, classes:, bake_subtitle: true, cases: false, bake_exercises: false)
|
|
7
7
|
book.notes.each do |note|
|
|
8
8
|
next unless (note.classes & classes).any?
|
|
9
9
|
|
|
10
|
-
bake_note(
|
|
10
|
+
bake_note(
|
|
11
|
+
note: note, bake_subtitle: bake_subtitle, cases: cases, bake_exercises: bake_exercises)
|
|
11
12
|
end
|
|
12
13
|
end
|
|
13
14
|
|
|
14
|
-
def self.bake_note(note:, bake_subtitle:, cases:
|
|
15
|
+
def self.bake_note(note:, bake_subtitle:, cases:, bake_exercises:)
|
|
15
16
|
Kitchen::Directions::BakeIframes.v1(outer_element: note)
|
|
16
17
|
note.wrap_children(class: 'os-note-body')
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
if bake_subtitle
|
|
20
|
+
BakeNoteSubtitle.v1(note: note, cases: cases)
|
|
21
|
+
else
|
|
22
|
+
note.title&.trash
|
|
23
|
+
end
|
|
19
24
|
|
|
20
25
|
note.prepend(child:
|
|
21
26
|
<<~HTML
|
|
@@ -24,6 +29,33 @@ module Kitchen
|
|
|
24
29
|
</h3>
|
|
25
30
|
HTML
|
|
26
31
|
)
|
|
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
|
|
27
59
|
end
|
|
28
60
|
end
|
|
29
61
|
end
|
|
@@ -9,6 +9,9 @@ module Kitchen::Directions
|
|
|
9
9
|
book.chapters.pages.notes("$.#{klass}").each do |note|
|
|
10
10
|
note.wrap_children(class: 'os-note-body')
|
|
11
11
|
previous_example = note.previous
|
|
12
|
+
until previous_example.nil? || previous_example[:'data-type'] == 'example'
|
|
13
|
+
previous_example = previous_example.previous
|
|
14
|
+
end
|
|
12
15
|
os_number = previous_example&.first('.os-number')&.children&.to_s
|
|
13
16
|
|
|
14
17
|
note.prepend(child:
|
|
@@ -29,6 +32,8 @@ module Kitchen::Directions
|
|
|
29
32
|
note.injected_questions.each do |question|
|
|
30
33
|
BakeNumberedNotes.bake_note_injected_question(note: note, question: question)
|
|
31
34
|
end
|
|
35
|
+
|
|
36
|
+
note.search("div[data-type='solution']").each&.trash if suppress_solution
|
|
32
37
|
end
|
|
33
38
|
end
|
|
34
39
|
end
|
|
@@ -62,6 +62,9 @@ module Kitchen
|
|
|
62
62
|
elsif table.column_header?
|
|
63
63
|
custom_table = CustomBody.new(table: table, klass: 'column-header')
|
|
64
64
|
custom_table.modify_body(has_fake_title: false)
|
|
65
|
+
elsif table.text_heavy?
|
|
66
|
+
custom_table = CustomBody.new(table: table, klass: 'text-heavy')
|
|
67
|
+
custom_table.modify_body(has_fake_title: false)
|
|
65
68
|
end
|
|
66
69
|
end
|
|
67
70
|
end
|
|
@@ -5,10 +5,11 @@ module Kitchen
|
|
|
5
5
|
# Bake directions for EOB references
|
|
6
6
|
#
|
|
7
7
|
module BakeReferences
|
|
8
|
-
def self.v1(book:, metadata_source:)
|
|
8
|
+
def self.v1(book:, metadata_source:, numbered_title: false)
|
|
9
9
|
V1.new.bake(
|
|
10
10
|
book: book,
|
|
11
|
-
metadata_source: metadata_source
|
|
11
|
+
metadata_source: metadata_source,
|
|
12
|
+
numbered_title: numbered_title
|
|
12
13
|
)
|
|
13
14
|
end
|
|
14
15
|
|
|
@@ -4,7 +4,7 @@ module Kitchen::Directions::BakeReferences
|
|
|
4
4
|
class V1
|
|
5
5
|
renderable
|
|
6
6
|
|
|
7
|
-
def bake(book:, metadata_source:)
|
|
7
|
+
def bake(book:, metadata_source:, numbered_title:)
|
|
8
8
|
@metadata = metadata_source.children_to_keep.copy
|
|
9
9
|
@klass = 'reference'
|
|
10
10
|
@uuid_prefix = '.'
|
|
@@ -28,12 +28,17 @@ module Kitchen::Directions::BakeReferences
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
chapter_references = chapter.pages.references.cut
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
chapter_title = if numbered_title
|
|
33
|
+
chapter.title.search('.os-number, .os-divider, .os-text')
|
|
34
|
+
else
|
|
35
|
+
chapter.title.search('.os-text')
|
|
36
|
+
end
|
|
32
37
|
|
|
33
38
|
chapter.append(child:
|
|
34
39
|
<<~HTML
|
|
35
40
|
<div class="os-chapter-area">
|
|
36
|
-
<h2 data-type="document-title">#{
|
|
41
|
+
<h2 data-type="document-title">#{chapter_title}</h2>
|
|
37
42
|
#{chapter_references.paste}
|
|
38
43
|
</div>
|
|
39
44
|
HTML
|
|
@@ -9,6 +9,7 @@ module Kitchen
|
|
|
9
9
|
table.remove_attribute('summary')
|
|
10
10
|
table.parent.add_class('os-unstyled-container') if table.unstyled?
|
|
11
11
|
table.parent.add_class('os-column-header-container') if table.column_header?
|
|
12
|
+
table.parent.add_class('os-top-titled-container') if table.top_titled?
|
|
12
13
|
end
|
|
13
14
|
end
|
|
14
15
|
end
|
|
@@ -38,7 +38,9 @@ module Kitchen::Directions::MoveSolutionsToAnswerKey
|
|
|
38
38
|
</div>
|
|
39
39
|
HTML
|
|
40
40
|
)
|
|
41
|
-
strategy.bake(
|
|
41
|
+
strategy.bake(
|
|
42
|
+
chapter: chapter, append_to: append_to.first("div[data-uuid-key='#{uuid_key}']")
|
|
43
|
+
)
|
|
42
44
|
end
|
|
43
45
|
# rubocop:enable Metrics/ParameterLists
|
|
44
46
|
end
|
data/lib/kitchen/element_base.rb
CHANGED
|
@@ -211,6 +211,14 @@ module Kitchen
|
|
|
211
211
|
self[:id] = value
|
|
212
212
|
end
|
|
213
213
|
|
|
214
|
+
# Returns the element's data-type
|
|
215
|
+
#
|
|
216
|
+
# @return [String]
|
|
217
|
+
#
|
|
218
|
+
def data_type
|
|
219
|
+
self[:'data-type']
|
|
220
|
+
end
|
|
221
|
+
|
|
214
222
|
# A way to set values and chain them
|
|
215
223
|
#
|
|
216
224
|
# @param property [String, Symbol] the name of the property to set
|
|
@@ -419,23 +427,6 @@ module Kitchen
|
|
|
419
427
|
)
|
|
420
428
|
end
|
|
421
429
|
|
|
422
|
-
# Searches for elements handled by a list of enumerator classes. All element that
|
|
423
|
-
# matches one of those enumerator classes are iterated over.
|
|
424
|
-
#
|
|
425
|
-
# @param enumerator_classes [Array<ElementEnumeratorBase>]
|
|
426
|
-
# @return [TypeCastingElementEnumerator]
|
|
427
|
-
#
|
|
428
|
-
def search_with(*enumerator_classes)
|
|
429
|
-
block_error_if(block_given?)
|
|
430
|
-
raise 'must supply at least one enumerator class' if enumerator_classes.empty?
|
|
431
|
-
|
|
432
|
-
factory = enumerator_classes[0].factory
|
|
433
|
-
enumerator_classes[1..-1].each do |enumerator_class|
|
|
434
|
-
factory = factory.or_with(enumerator_class.factory)
|
|
435
|
-
end
|
|
436
|
-
factory.build_within(self)
|
|
437
|
-
end
|
|
438
|
-
|
|
439
430
|
# Removes the element from its parent and places it on the specified clipboard
|
|
440
431
|
#
|
|
441
432
|
# @param to [Symbol, String, Clipboard, nil] the name of the clipboard (or a Clipboard
|
|
@@ -762,7 +753,8 @@ module Kitchen
|
|
|
762
753
|
# Returns a pages enumerator
|
|
763
754
|
def_delegators :as_enumerator, :pages, :chapters, :terms, :figures, :notes, :tables, :examples,
|
|
764
755
|
:metadatas, :non_introduction_pages, :units, :titles, :exercises, :references,
|
|
765
|
-
:composite_pages, :composite_chapters, :solutions, :injected_questions
|
|
756
|
+
:composite_pages, :composite_chapters, :solutions, :injected_questions,
|
|
757
|
+
:search_with
|
|
766
758
|
|
|
767
759
|
# Returns this element as an enumerator (over only one element, itself)
|
|
768
760
|
#
|
|
@@ -327,6 +327,23 @@ module Kitchen
|
|
|
327
327
|
chain_to(ElementEnumerator, css_or_xpath: css_or_xpath, only: only, except: except)
|
|
328
328
|
end
|
|
329
329
|
|
|
330
|
+
# Searches for elements handled by a list of enumerator classes. All element that
|
|
331
|
+
# matches one of those enumerator classes are iterated over.
|
|
332
|
+
#
|
|
333
|
+
# @param enumerator_classes [Array<ElementEnumeratorBase>]
|
|
334
|
+
# @return [TypeCastingElementEnumerator]
|
|
335
|
+
#
|
|
336
|
+
def search_with(*enumerator_classes)
|
|
337
|
+
block_error_if(block_given?)
|
|
338
|
+
raise 'must supply at least one enumerator class' if enumerator_classes.empty?
|
|
339
|
+
|
|
340
|
+
factory = enumerator_classes[0].factory
|
|
341
|
+
enumerator_classes[1..-1].each do |enumerator_class|
|
|
342
|
+
factory = factory.or_with(enumerator_class.factory)
|
|
343
|
+
end
|
|
344
|
+
factory.build_within(self)
|
|
345
|
+
end
|
|
346
|
+
|
|
330
347
|
# Returns an enumerator that iterates through elements within the scope of this enumerator
|
|
331
348
|
#
|
|
332
349
|
# @param enumerator_class [ElementEnumeratorBase] the enumerator to use for the iteration
|
|
@@ -33,7 +33,8 @@ module Kitchen
|
|
|
33
33
|
title.parent.has_class?('os-caption-container') || \
|
|
34
34
|
title.parent.has_class?('os-caption') || \
|
|
35
35
|
title.parent.name == 'caption' || \
|
|
36
|
-
title.parent
|
|
36
|
+
title.parent.data_type == 'note' || \
|
|
37
|
+
title.parent.data_type == 'exercise'
|
|
37
38
|
end
|
|
38
39
|
)
|
|
39
40
|
end
|
|
@@ -39,6 +39,14 @@ module Kitchen
|
|
|
39
39
|
first("div[data-type='solution']")
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# Returns the enumerator for solutions
|
|
43
|
+
#
|
|
44
|
+
# @return [ElementEnumerator]
|
|
45
|
+
#
|
|
46
|
+
def solutions
|
|
47
|
+
search("div[data-type='solution']")
|
|
48
|
+
end
|
|
49
|
+
|
|
42
50
|
# Returns whether the exercise has been baked
|
|
43
51
|
#
|
|
44
52
|
# @return [Boolean]
|
|
@@ -46,5 +54,39 @@ module Kitchen
|
|
|
46
54
|
def baked?
|
|
47
55
|
search('div.os-problem-container').any?
|
|
48
56
|
end
|
|
57
|
+
|
|
58
|
+
# Returns true if the exercise's title is autogenerated
|
|
59
|
+
#
|
|
60
|
+
# @return [Boolean]
|
|
61
|
+
#
|
|
62
|
+
def indicates_autogenerated_title?
|
|
63
|
+
detected_exercise_title_key != 0 && detected_exercise_title_key.present?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Get the autogenerated title for this note
|
|
67
|
+
#
|
|
68
|
+
# @return [String]
|
|
69
|
+
#
|
|
70
|
+
def autogenerated_title
|
|
71
|
+
if indicates_autogenerated_title?
|
|
72
|
+
I18n.t(:"exercises.#{detected_exercise_title_key}")
|
|
73
|
+
else
|
|
74
|
+
"unknown title for exercise with classes #{classes}"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def detected_exercise_title_key
|
|
79
|
+
@detected_exercise_title_key ||= begin
|
|
80
|
+
return 0 if classes.empty? || !I18n.t('.').key?(:exercises)
|
|
81
|
+
|
|
82
|
+
possible_keys = I18n.t(:exercises).keys.map(&:to_s)
|
|
83
|
+
keys = possible_keys & classes
|
|
84
|
+
|
|
85
|
+
raise("too many translation keys: #{keys.join(', ')}") if keys.many?
|
|
86
|
+
return 0 if keys.empty?
|
|
87
|
+
|
|
88
|
+
keys.first
|
|
89
|
+
end
|
|
90
|
+
end
|
|
49
91
|
end
|
|
50
92
|
end
|
|
@@ -53,7 +53,7 @@ module Kitchen
|
|
|
53
53
|
# @return [Boolean]
|
|
54
54
|
#
|
|
55
55
|
def figure_to_bake?
|
|
56
|
-
return false if subfigure? || (has_class?('unnumbered') && !has_class?('splash'))
|
|
56
|
+
return false if subfigure? || (has_class?('unnumbered') && !has_class?('splash') && !caption)
|
|
57
57
|
|
|
58
58
|
true
|
|
59
59
|
end
|
|
@@ -27,7 +27,12 @@ module Kitchen
|
|
|
27
27
|
# @return [ElementEnumerator]
|
|
28
28
|
#
|
|
29
29
|
def children_to_keep
|
|
30
|
-
search(%w(span[data-type='revised']
|
|
30
|
+
search(%w(span[data-type='revised']
|
|
31
|
+
span[data-type='slug']
|
|
32
|
+
div.authors
|
|
33
|
+
div.publishers
|
|
34
|
+
div.print-style
|
|
35
|
+
div.permissions
|
|
31
36
|
div[data-type='subject']))
|
|
32
37
|
end
|
|
33
38
|
end
|
data/lib/kitchen/note_element.rb
CHANGED
|
@@ -29,16 +29,30 @@ module Kitchen
|
|
|
29
29
|
#
|
|
30
30
|
def title
|
|
31
31
|
block_error_if(block_given?)
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
# An element with data-type="title" is ambiguous; it is only the note's title if:
|
|
33
|
+
# 1. it is the note body's first child
|
|
34
|
+
# 2. it is the first child's first child and the first child is a paragraph
|
|
35
|
+
first_child = first_note_body_child
|
|
36
|
+
return unless first_child
|
|
37
|
+
|
|
38
|
+
first_grandchild = get_first_grandchild_for_title(first_child)
|
|
34
39
|
|
|
35
|
-
if first_child
|
|
40
|
+
if first_child.data_type == 'title'
|
|
36
41
|
first_child
|
|
37
|
-
elsif
|
|
38
|
-
|
|
42
|
+
elsif first_grandchild&.data_type == 'title'
|
|
43
|
+
first_grandchild
|
|
39
44
|
end
|
|
40
45
|
end
|
|
41
46
|
|
|
47
|
+
def first_note_body_child
|
|
48
|
+
note_body = first('div.os-note-body')
|
|
49
|
+
note_body ? note_body.element_children[0] : element_children[0]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def get_first_grandchild_for_title(first_child)
|
|
53
|
+
first_child&.element_children&.[](0) if first_child.name == 'p'
|
|
54
|
+
end
|
|
55
|
+
|
|
42
56
|
# Returns true if the note's title is autogenerated
|
|
43
57
|
#
|
|
44
58
|
# @return [Boolean]
|
|
@@ -97,6 +97,14 @@ module Kitchen
|
|
|
97
97
|
has_class?('column-header')
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
+
# Returns true if the table is text heavy
|
|
101
|
+
#
|
|
102
|
+
# @return [Boolean]
|
|
103
|
+
#
|
|
104
|
+
def text_heavy?
|
|
105
|
+
has_class?('text-heavy')
|
|
106
|
+
end
|
|
107
|
+
|
|
100
108
|
# Returns an element for the table caption, if present
|
|
101
109
|
#
|
|
102
110
|
# @return [Element, nil]
|
data/lib/kitchen/version.rb
CHANGED
data/lib/locales/en.yml
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: 12.2.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-
|
|
11
|
+
date: 2021-10-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -243,9 +243,12 @@ files:
|
|
|
243
243
|
- lib/kitchen/counter.rb
|
|
244
244
|
- lib/kitchen/debug/print_recipe_error.rb
|
|
245
245
|
- lib/kitchen/directions/.rubocop.yml
|
|
246
|
+
- lib/kitchen/directions/bake_accessibility_fixes.rb
|
|
246
247
|
- lib/kitchen/directions/bake_annotation_classes/main.rb
|
|
247
248
|
- lib/kitchen/directions/bake_annotation_classes/v1.rb
|
|
248
249
|
- lib/kitchen/directions/bake_appendix.rb
|
|
250
|
+
- lib/kitchen/directions/bake_autotitled_exercise/main.rb
|
|
251
|
+
- lib/kitchen/directions/bake_autotitled_exercise/v1.rb
|
|
249
252
|
- lib/kitchen/directions/bake_chapter_glossary/main.rb
|
|
250
253
|
- lib/kitchen/directions/bake_chapter_glossary/v1.rb
|
|
251
254
|
- lib/kitchen/directions/bake_chapter_introductions/bake_chapter_objectives.rb
|
|
@@ -291,8 +294,10 @@ files:
|
|
|
291
294
|
- lib/kitchen/directions/bake_index/v1.rb
|
|
292
295
|
- lib/kitchen/directions/bake_index/v1.xhtml.erb
|
|
293
296
|
- lib/kitchen/directions/bake_injected_exercise.rb
|
|
294
|
-
- lib/kitchen/directions/
|
|
297
|
+
- lib/kitchen/directions/bake_injected_exercise/add_injected_exercise_id.rb
|
|
298
|
+
- lib/kitchen/directions/bake_injected_exercise/bake_injected_exercise_question.rb
|
|
295
299
|
- lib/kitchen/directions/bake_inline_lists.rb
|
|
300
|
+
- lib/kitchen/directions/bake_learning_objectives.rb
|
|
296
301
|
- lib/kitchen/directions/bake_link_placeholders.rb
|
|
297
302
|
- lib/kitchen/directions/bake_lists_with_para.rb
|
|
298
303
|
- lib/kitchen/directions/bake_math_in_paragraph.rb
|
|
@@ -310,7 +315,6 @@ files:
|
|
|
310
315
|
- lib/kitchen/directions/bake_numbered_table/main.rb
|
|
311
316
|
- lib/kitchen/directions/bake_numbered_table/v1.rb
|
|
312
317
|
- lib/kitchen/directions/bake_numbered_table/v2.rb
|
|
313
|
-
- lib/kitchen/directions/bake_page_abstracts.rb
|
|
314
318
|
- lib/kitchen/directions/bake_preface/main.rb
|
|
315
319
|
- lib/kitchen/directions/bake_preface/v1.rb
|
|
316
320
|
- lib/kitchen/directions/bake_references/main.rb
|