openstax_kitchen 11.0.0 → 11.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/kitchen/composite_page_element.rb +8 -0
  5. data/lib/kitchen/directions/bake_chapter_introductions/bake_chapter_objectives.rb +46 -0
  6. data/lib/kitchen/directions/bake_chapter_introductions/bake_chapter_outline.rb +14 -0
  7. data/lib/kitchen/directions/bake_chapter_introductions/main.rb +43 -0
  8. data/lib/kitchen/directions/bake_chapter_introductions/v1.rb +56 -0
  9. data/lib/kitchen/directions/bake_chapter_introductions/v2.rb +91 -0
  10. data/lib/kitchen/directions/bake_custom_sections/main.rb +14 -0
  11. data/lib/kitchen/directions/bake_custom_sections/v1.rb +42 -0
  12. data/lib/kitchen/directions/bake_equations.rb +2 -3
  13. data/lib/kitchen/directions/bake_example.rb +4 -5
  14. data/lib/kitchen/directions/bake_figure.rb +5 -3
  15. data/lib/kitchen/directions/bake_iframes/main.rb +11 -0
  16. data/lib/kitchen/directions/bake_iframes/v1.rb +25 -0
  17. data/lib/kitchen/directions/bake_index/main.rb +2 -2
  18. data/lib/kitchen/directions/bake_index/v1.rb +39 -7
  19. data/lib/kitchen/directions/bake_index/v1.xhtml.erb +3 -3
  20. data/lib/kitchen/directions/bake_injected_exercise.rb +18 -0
  21. data/lib/kitchen/directions/bake_injected_exercise_question.rb +71 -0
  22. data/lib/kitchen/directions/bake_link_placeholders.rb +15 -2
  23. data/lib/kitchen/directions/bake_lists_with_para.rb +3 -3
  24. data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +5 -5
  25. data/lib/kitchen/directions/bake_notes/bake_note_subtitle.rb +6 -2
  26. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/main.rb +13 -3
  27. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v1.rb +29 -25
  28. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v2.rb +22 -17
  29. data/lib/kitchen/directions/bake_notes/bake_numbered_notes/v3.rb +27 -22
  30. data/lib/kitchen/directions/bake_numbered_exercise/main.rb +3 -2
  31. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +6 -24
  32. data/lib/kitchen/directions/bake_numbered_table/bake_table_body.rb +3 -3
  33. data/lib/kitchen/directions/bake_numbered_table/main.rb +4 -4
  34. data/lib/kitchen/directions/bake_numbered_table/v1.rb +3 -3
  35. data/lib/kitchen/directions/bake_numbered_table/v2.rb +3 -3
  36. data/lib/kitchen/directions/bake_toc.rb +1 -1
  37. data/lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_exercise_section.rb +1 -7
  38. data/lib/kitchen/directions/move_solutions_to_answer_key/move_solutions_from_numbered_note.rb +1 -7
  39. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/contemporary_math.rb +17 -0
  40. data/lib/kitchen/element_base.rb +38 -2
  41. data/lib/kitchen/element_enumerator_base.rb +35 -0
  42. data/lib/kitchen/injected_question_element.rb +77 -0
  43. data/lib/kitchen/injected_question_element_enumerator.rb +21 -0
  44. data/lib/kitchen/selectors/base.rb +6 -0
  45. data/lib/kitchen/selectors/standard_1.rb +3 -0
  46. data/lib/kitchen/solution_element_enumerator.rb +21 -0
  47. data/lib/kitchen/version.rb +1 -1
  48. data/lib/locales/en.yml +6 -4
  49. data/lib/locales/es.yml +5 -4
  50. data/lib/locales/pl.yml +52 -7
  51. metadata +17 -6
  52. data/lib/kitchen/directions/bake_chapter_introductions/chapter_introduction.xhtml.erb +0 -0
  53. data/lib/kitchen/directions/bake_chapter_introductions.rb +0 -65
  54. data/lib/kitchen/directions/bake_notes/bake_note_iframes.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6964a7fe85234e82e7f54f3b6d4980633f4f4c29c49d3123743c214d9f46653
4
- data.tar.gz: 2426f1990ae74d35d2ac098bcf7d5c09aa5094eeef598dd9658d8fedf97916c4
3
+ metadata.gz: 4340461612470e8ddff3976af6bf342821a18f1e01c70d5c6d4dcbf08636ac24
4
+ data.tar.gz: 293967ff3cf8af70f6d9d5f5d20866c77608af41c279590b3abb39966813f048
5
5
  SHA512:
6
- metadata.gz: faba0041d8c958c3ffa369dbe2d0c5453f8a236bedd0654e362afa65c84093ec22771dadaa9a313e688f6644681267b63f263ba60af9d1b81a211bc3c98a5df1
7
- data.tar.gz: a1e8ff40b3377508904ab62980302f129527755512f58506c805d7ae1507977ce65f1c993786cdeffc5f3871e4448e5d4df264979539d60f995d7f9c7b3ece48
6
+ metadata.gz: 70eedaaa535e97066b5b5b0d80e9c8916ffb6de5ecdf063f7a58d2c984253771742832278e53f5ce8bea3f0f3c7cbdd97da058258e5ace42dda0da372243ff2d
7
+ data.tar.gz: 72001901b5c82c46bd835521d9a815d178cc6bcea04502fd6b9b10bf36309ed42028b92714fd003e1a0042c60ce9eb4ab505dc627d8dd763f9c6892ff1fee7ea
data/CHANGELOG.md CHANGED
@@ -6,6 +6,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [11.1.0] - 2021-08-30
10
+
11
+ * Update injected questions to synthesize ids during baking (minor)
12
+ * Fix `BakeListsWithPara` to copy all children from para not just text (minor)
13
+ * Implement labels with cases to `BakeAutotitledNotes` and `BakeNumberedNotes` (minor)
14
+ * Add ids to injected questions (minor)
15
+ * Create `BakeIframes` outer directory to allow bake iframes also from outside notes, remove `BakeNoteIFrames` module from notes directory (minor)
16
+ * Update the contemporary math `Strategy` to target injected solution sections (minor)
17
+ * Update `BakeNumberedNotes` to handle injected questions in notes (minor)
18
+ * Create `InjectedQuestionElement` and `InjectedQuestionElementEnumerator` classes (minor)
19
+ * Create `BakeInjectedExercise` and `BakeInjectedExerciseQuestion` directions (minor)
20
+ * Update `MoveSolutionsFromExerciseSection` and `MoveSolutionsFromNumberedNote` to move injected solutions (minor)
21
+ * Add `SolutionElementEnumerator` to support the above (minor)
22
+ * Remove multipart exercise baking from `BakeNumberedExercise`; this is now done in `InjectedExercise` directions (patch)
23
+ * Modify target labels to use grammatical cases (minor)
24
+ * Modify `BakeIndex` to bake multiple types of indexes (minor)
25
+ * Create `v2` in `BakeChapterIntroductions` that should replace `v1` (minor)
26
+ * Added a DEPRECATION warning in `v1` for `BakeChapterIntroductions` (minor)
27
+ * Added a bit more description to deprecation warning for `BakeChapterIntroductions.v1` (minor)
28
+
9
29
  ## [11.0.0] - 2021-08-6
10
30
 
11
31
  * Add `ChangeSubsectionTitleTag` direction for modifying eoc sections (minor)
@@ -20,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
20
40
  * Adds `PageElement#count_in_chapter_without_intro_page` (minor)
21
41
  * Adds `ChapterElement#has_introduction?` (minor)
22
42
  * Adds `BakeFolio` to set spanish translation variables in the html tag for folio-pdf purposes (minor)
43
+ * Create `BakeCustomSections` direction for English Composition (minor)
23
44
  * Create `BakeAnnotationClasses` v1 for English Composition (minor)
24
45
 
25
46
  ## [10.0.0] - 2021-07-30
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openstax_kitchen (11.0.0)
4
+ openstax_kitchen (11.1.0)
5
5
  activesupport
6
6
  i18n
7
7
  nokogiri
@@ -41,6 +41,14 @@ module Kitchen
41
41
  has_class?('os-index-container')
42
42
  end
43
43
 
44
+ # Returns true if this page is a book index of type
45
+ #
46
+ # @return [Boolean]
47
+ #
48
+ def is_index_of_type?
49
+ (self[:class] || '').match?(/os-index-.+-container/)
50
+ end
51
+
44
52
  # In books we can find two types of EOB References.
45
53
  #
46
54
  # One of them has form similar to footnotes. There are citation links in the text that provides
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class BakeChapterObjectives
5
+ def bake(chapter:, strategy:)
6
+ case strategy
7
+ when :default
8
+ bake_as_note(chapter: chapter)
9
+ when :add_objectives
10
+ add_chapter_objectives(chapter: chapter)
11
+ when :none
12
+ ''
13
+ else
14
+ raise 'No such strategy'
15
+ end
16
+ end
17
+
18
+ def bake_as_note(chapter:)
19
+ chapter_objectives_note = chapter.notes('$.chapter-objectives').first
20
+
21
+ # trash existing title
22
+ chapter_objectives_note.titles.first&.trash
23
+ Kitchen::Directions::BakeAutotitledNotes.v1(
24
+ book: chapter,
25
+ classes: %w[chapter-objectives],
26
+ bake_subtitle: false
27
+ )
28
+
29
+ chapter_objectives_note.cut.paste
30
+ end
31
+
32
+ def add_chapter_objectives(chapter:)
33
+ chapter.non_introduction_pages.map do |page|
34
+ <<~HTML
35
+ <div class="os-chapter-objective">
36
+ <a class="os-chapter-objective" href="##{page.title[:id]}">
37
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
38
+ <span class="os-divider"> </span>
39
+ <span data-type="" itemprop="" class="os-text">#{page.title.children[0].text}</span>
40
+ </a>
41
+ </div>
42
+ HTML
43
+ end.join('')
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class BakeChapterOutline
5
+ def bake(chapter_objectives_html:)
6
+ <<~HTML
7
+ <div class="os-chapter-outline">
8
+ <h3 class="os-title">#{I18n.t(:chapter_outline)}</h3>
9
+ #{chapter_objectives_html}
10
+ </div>
11
+ HTML
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeChapterIntroductions
6
+ def self.v1(book:)
7
+ V1.new.bake(
8
+ book: book
9
+ )
10
+ end
11
+
12
+ def self.v2(
13
+ book:,
14
+ strategy_options: {
15
+ strategy: :default, bake_chapter_outline: false, introduction_order: :v1
16
+ }
17
+ )
18
+ V2.new.bake(
19
+ book: book,
20
+ strategy_options: strategy_options
21
+ )
22
+ end
23
+
24
+ def self.bake_chapter_objectives(chapter:, strategy:)
25
+ BakeChapterObjectives.new.bake(
26
+ chapter: chapter,
27
+ strategy: strategy
28
+ )
29
+ end
30
+
31
+ def self.bake_chapter_outline(chapter_objectives_html:)
32
+ BakeChapterOutline.new.bake(
33
+ chapter_objectives_html: chapter_objectives_html
34
+ )
35
+ end
36
+
37
+ def self.v1_update_selectors(something_with_selectors)
38
+ something_with_selectors.selectors.title_in_introduction_page =
39
+ ".intro-text > [data-type='document-title']"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class V1
5
+ def bake(book:)
6
+ # <b>DEPRECATED:</b> Please use <tt>v2</tt> instead.
7
+ warn '[DEPRECATION] `BakeChapterIntroductions.v1` is deprecated. Please use `v2` instead.'
8
+
9
+ book.chapters.each do |chapter|
10
+ introduction_page = chapter.introduction_page
11
+
12
+ introduction_page.search("div[data-type='description']").trash
13
+ introduction_page.search("div[data-type='abstract']").trash
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)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterIntroductions
4
+ class V2
5
+ def bake(book:, strategy_options:)
6
+ book.chapters.each do |chapter|
7
+ introduction_page = chapter.introduction_page
8
+ title = bake_title(introduction_page: introduction_page)
9
+
10
+ chapter_intro_html =
11
+ Kitchen::Directions::BakeChapterIntroductions.bake_chapter_objectives(
12
+ chapter: chapter,
13
+ strategy: strategy_options[:strategy]
14
+ )
15
+
16
+ if strategy_options[:bake_chapter_outline]
17
+ chapter_intro_html =
18
+ Kitchen::Directions::BakeChapterIntroductions.bake_chapter_outline(
19
+ chapter_objectives_html: chapter_intro_html
20
+ )
21
+ end
22
+
23
+ case strategy_options[:introduction_order]
24
+ when :v1
25
+ v1_introduction_order(
26
+ introduction_page: introduction_page,
27
+ chapter_intro_html: chapter_intro_html,
28
+ title: title
29
+ )
30
+ when :v2
31
+ v2_introduction_order(
32
+ introduction_page: introduction_page,
33
+ chapter_intro_html: chapter_intro_html,
34
+ title: title
35
+ )
36
+ end
37
+ end
38
+
39
+ Kitchen::Directions::BakeChapterIntroductions.v1_update_selectors(book)
40
+ end
41
+
42
+ def v1_introduction_order(introduction_page:, chapter_intro_html:, title:)
43
+ intro_content = introduction_page.search(
44
+ "> :not([data-type='metadata']):not(.splash):not(.has-splash)"
45
+ ).cut
46
+
47
+ introduction_page.append(child:
48
+ <<~HTML
49
+ <div class="intro-body">
50
+ #{chapter_intro_html}
51
+ <div class="intro-text">
52
+ #{title.paste}
53
+ #{intro_content.paste}
54
+ </div>
55
+ </div>
56
+ HTML
57
+ )
58
+ end
59
+
60
+ def v2_introduction_order(introduction_page:, chapter_intro_html:, title:)
61
+ if chapter_intro_html.empty?
62
+ chapter_intro_html = introduction_page.notes('$.chapter-objectives').first&.cut&.paste
63
+ end
64
+ extra_content = introduction_page.search(
65
+ '> :not([data-type="metadata"]):not(.splash):not(.has-splash)'
66
+ ).cut
67
+
68
+ introduction_page.append(child:
69
+ <<~HTML
70
+ <div class="intro-body">
71
+ #{chapter_intro_html}
72
+ <div class="intro-text">
73
+ #{title.paste}
74
+ #{extra_content.paste}
75
+ </div>
76
+ </div>
77
+ HTML
78
+ )
79
+ end
80
+
81
+ def bake_title(introduction_page:)
82
+ introduction_page.search(
83
+ 'div[data-type="description"], div[data-type="abstract"]'
84
+ ).each(&:trash)
85
+
86
+ title = introduction_page.title.cut
87
+ title.name = 'h2'
88
+ Kitchen::Directions::MoveTitleTextIntoSpan.v1(title: title)
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeCustomSections
6
+ def self.v1(chapter:, custom_sections_properties:)
7
+ V1.new.bake(
8
+ chapter: chapter,
9
+ custom_sections_properties: custom_sections_properties
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeCustomSections
4
+ class V1
5
+ def bake(chapter:, custom_sections_properties:)
6
+ custom_sections_properties.each do |_custom_section_name, property|
7
+ title_text = I18n.t(:"custom-sections.#{property[:class]}")
8
+ property_class = property[:class]
9
+ inject = property[:inject]
10
+ chapter.search(".#{property_class}").each do |custom_section|
11
+
12
+ case inject
13
+ when 'title'
14
+ custom_section_title = custom_section.first('h2')
15
+ custom_section_title_os_text = custom_section_title.first('.os-text')
16
+ custom_section_title_sibling = custom_section.first('h2 + div')
17
+ div_id = custom_section_title_sibling['id']
18
+ custom_section_title_sibling.trash
19
+ custom_section_title.append(sibling:
20
+ <<~HTML
21
+ <h3 class="os-subtitle" id="#{div_id}">#{custom_section_title_os_text.text}</h3>
22
+ HTML
23
+ )
24
+ custom_section_title_os_text.replace_children(with: title_text)
25
+ when 'subtitle'
26
+ custom_section_title = custom_section.titles.first
27
+ custom_section_title.name = 'h4'
28
+ custom_section_title.prepend(sibling:
29
+ <<~HTML
30
+ <h3 class="os-title">#{title_text}</h3>
31
+ HTML
32
+ )
33
+ when 'title_prefix'
34
+ custom_section_title = custom_section.titles.first
35
+ custom_section_title.replace_children(with: "#{title_text}: " +
36
+ custom_section_title.text)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -3,14 +3,13 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeEquations
6
- def self.v1(book:, number_decorator: :none)
6
+ def self.v1(book:, number_decorator: :none, cases: false)
7
7
  book.chapters.search('div[data-type="equation"]:not(.unnumbered)').each do |eq|
8
8
  chapter = eq.ancestor(:chapter)
9
9
  number = "#{chapter.count_in(:book)}.#{eq.count_in(:chapter)}"
10
10
 
11
11
  # Store label information
12
- equation_label = "#{I18n.t(:equation)} #{number}"
13
- book.pantry(name: :link_text).store equation_label, label: eq.id
12
+ eq.target_label(label_text: 'equation', custom_content: number, cases: cases)
14
13
 
15
14
  decorated_number =
16
15
  case number_decorator
@@ -3,22 +3,21 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeExample
6
- def self.v1(example:, number:, title_tag:, numbered_solutions: false)
6
+ def self.v1(example:, number:, title_tag:, numbered_solutions: false, cases: false)
7
7
  example.wrap_children(class: 'body')
8
8
 
9
9
  example.prepend(child:
10
10
  <<~HTML
11
11
  <#{title_tag} class="os-title">
12
- <span class="os-title-label">#{I18n.t(:example_label)} </span>
12
+ <span class="os-title-label">#{I18n.t("example#{'.nominative' if cases}")} </span>
13
13
  <span class="os-number">#{number}</span>
14
14
  <span class="os-divider"> </span>
15
15
  </#{title_tag}>
16
16
  HTML
17
17
  )
18
18
 
19
- example.document
20
- .pantry(name: :link_text)
21
- .store("#{I18n.t(:example_label)} #{number}", label: example.id)
19
+ # Store label information
20
+ example.target_label(label_text: 'example', custom_content: number, cases: cases)
22
21
 
23
22
  example.titles_to_rename.each do |title|
24
23
  title.name = 'h4'
@@ -3,7 +3,7 @@
3
3
  module Kitchen
4
4
  module Directions
5
5
  module BakeFigure
6
- def self.v1(figure:, number:)
6
+ def self.v1(figure:, number:, cases: false)
7
7
  return if figure.has_class?('unnumbered') && !figure.has_class?('splash')
8
8
 
9
9
  figure.wrap(%(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
@@ -19,14 +19,16 @@ module Kitchen
19
19
  return
20
20
  end
21
21
 
22
- figure.pantry(name: :link_text).store "#{I18n.t(:figure)} #{number}", label: figure.id
22
+ # Store label information
23
+ figure.target_label(label_text: 'figure', custom_content: number, cases: cases)
24
+
23
25
  title = figure.title&.cut
24
26
 
25
27
  caption = figure.caption&.cut
26
28
  figure.append(sibling:
27
29
  <<~HTML
28
30
  <div class="os-caption-container">
29
- <span class="os-title-label">#{I18n.t(:figure)} </span>
31
+ <span class="os-title-label">#{I18n.t("figure#{'.nominative' if cases}")} </span>
30
32
  <span class="os-number">#{number}</span>
31
33
  <span class="os-divider"> </span>
32
34
  #{"<span class=\"os-title\" data-type=\"title\" id=\"#{title.id}\">#{title.children}</span>" if title}