openstax_kitchen 1.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/devcontainer.json +37 -17
  3. data/.github/config.yml +14 -0
  4. data/.github/workflows/tests.yml +5 -15
  5. data/.gitignore +2 -2
  6. data/.inch.yml +6 -0
  7. data/.rubocop.yml +65 -0
  8. data/CHANGELOG.md +85 -2
  9. data/Gemfile +5 -3
  10. data/Gemfile.lock +66 -18
  11. data/README.md +69 -15
  12. data/Rakefile +5 -3
  13. data/bin/console +4 -3
  14. data/docker/Dockerfile +36 -0
  15. data/docker/Dockerfile.ci +10 -0
  16. data/docker/bash +5 -1
  17. data/docker/build +10 -0
  18. data/docker/ci +15 -0
  19. data/docker/run +9 -0
  20. data/docker/tag_and_push_latest +17 -0
  21. data/lefthook.yml +6 -0
  22. data/lib/kitchen/ancestor.rb +38 -1
  23. data/lib/kitchen/book_document.rb +20 -2
  24. data/lib/kitchen/book_element.rb +40 -5
  25. data/lib/kitchen/book_element_enumerator.rb +4 -0
  26. data/lib/kitchen/book_recipe.rb +15 -1
  27. data/lib/kitchen/chapter_element.rb +43 -6
  28. data/lib/kitchen/chapter_element_enumerator.rb +9 -1
  29. data/lib/kitchen/clipboard.rb +35 -4
  30. data/lib/kitchen/composite_chapter_element.rb +21 -6
  31. data/lib/kitchen/composite_page_element.rb +35 -7
  32. data/lib/kitchen/composite_page_element_enumerator.rb +9 -1
  33. data/lib/kitchen/config.rb +20 -6
  34. data/lib/kitchen/counter.rb +9 -2
  35. data/lib/kitchen/debug/print_recipe_error.rb +53 -35
  36. data/lib/kitchen/directions/.rubocop.yml +22 -0
  37. data/lib/kitchen/directions/bake_appendix.rb +4 -4
  38. data/lib/kitchen/directions/bake_chapter_glossary/main.rb +18 -0
  39. data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +30 -0
  40. data/lib/kitchen/directions/bake_chapter_introductions.rb +7 -7
  41. data/lib/kitchen/directions/bake_chapter_key_concepts/main.rb +16 -0
  42. data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +35 -0
  43. data/lib/kitchen/directions/bake_chapter_key_equations.rb +30 -20
  44. data/lib/kitchen/directions/bake_chapter_section_exercises/main.rb +11 -0
  45. data/lib/kitchen/directions/bake_chapter_section_exercises/v1.rb +28 -0
  46. data/lib/kitchen/directions/bake_chapter_summary.rb +45 -36
  47. data/lib/kitchen/directions/bake_chapter_title/main.rb +11 -0
  48. data/lib/kitchen/directions/bake_chapter_title/v1.rb +24 -0
  49. data/lib/kitchen/directions/bake_checkpoint.rb +44 -0
  50. data/lib/kitchen/directions/bake_composite_chapters.rb +14 -0
  51. data/lib/kitchen/directions/bake_composite_pages.rb +2 -2
  52. data/lib/kitchen/directions/bake_equations.rb +37 -0
  53. data/lib/kitchen/directions/bake_example.rb +39 -11
  54. data/lib/kitchen/directions/bake_figure.rb +8 -5
  55. data/lib/kitchen/directions/bake_first_elements.rb +16 -0
  56. data/lib/kitchen/directions/bake_footnotes/main.rb +2 -2
  57. data/lib/kitchen/directions/bake_footnotes/v1.rb +6 -5
  58. data/lib/kitchen/directions/bake_free_response/free_response.xhtml.erb +10 -0
  59. data/lib/kitchen/directions/bake_free_response/main.rb +11 -0
  60. data/lib/kitchen/directions/bake_free_response/v1.rb +29 -0
  61. data/lib/kitchen/directions/bake_further_research.rb +59 -0
  62. data/lib/kitchen/directions/bake_index/main.rb +2 -2
  63. data/lib/kitchen/directions/bake_index/v1.rb +46 -18
  64. data/lib/kitchen/directions/bake_link_placeholders.rb +24 -0
  65. data/lib/kitchen/directions/bake_math_in_paragraph.rb +5 -3
  66. data/lib/kitchen/directions/bake_non_introduction_pages.rb +26 -0
  67. data/lib/kitchen/directions/bake_notes/bake_autotitled_notes.rb +29 -0
  68. data/lib/kitchen/directions/bake_notes/bake_note_subtitle.rb +22 -0
  69. data/lib/kitchen/directions/bake_notes/bake_numbered_notes.rb +51 -0
  70. data/lib/kitchen/directions/bake_notes/bake_unclassified_notes.rb +30 -0
  71. data/lib/kitchen/directions/bake_numbered_exercise/main.rb +15 -0
  72. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +47 -0
  73. data/lib/kitchen/directions/bake_numbered_table/main.rb +4 -4
  74. data/lib/kitchen/directions/bake_numbered_table/v1.rb +37 -18
  75. data/lib/kitchen/directions/bake_page_abstracts.rb +30 -0
  76. data/lib/kitchen/directions/bake_preface/main.rb +11 -0
  77. data/lib/kitchen/directions/bake_preface/v1.rb +18 -0
  78. data/lib/kitchen/directions/bake_references/main.rb +16 -0
  79. data/lib/kitchen/directions/bake_references/v1.rb +48 -0
  80. data/lib/kitchen/directions/bake_stepwise.rb +8 -12
  81. data/lib/kitchen/directions/bake_suggested_reading.rb +31 -0
  82. data/lib/kitchen/directions/bake_theorem/main.rb +11 -0
  83. data/lib/kitchen/directions/bake_theorem/v1.rb +28 -0
  84. data/lib/kitchen/directions/bake_toc.rb +49 -22
  85. data/lib/kitchen/directions/bake_unit_title/main.rb +11 -0
  86. data/lib/kitchen/directions/bake_unit_title/v1.rb +23 -0
  87. data/lib/kitchen/directions/bake_unnumbered_tables.rb +7 -5
  88. data/lib/kitchen/directions/book_answer_key_container/eob_solutions_container.xhtml.erb +9 -0
  89. data/lib/kitchen/directions/book_answer_key_container/main.rb +11 -0
  90. data/lib/kitchen/directions/book_answer_key_container/v1.rb +13 -0
  91. data/lib/kitchen/directions/chapter_review_container/chapter_review.xhtml.erb +9 -0
  92. data/lib/kitchen/directions/chapter_review_container/main.rb +11 -0
  93. data/lib/kitchen/directions/chapter_review_container/v1.rb +13 -0
  94. data/lib/kitchen/directions/eoc_section_title_link_snippet.rb +20 -0
  95. data/lib/kitchen/directions/move_exercises_to_eoc/main.rb +27 -0
  96. data/lib/kitchen/directions/move_exercises_to_eoc/v1.rb +36 -0
  97. data/lib/kitchen/directions/move_exercises_to_eoc/v2.rb +49 -0
  98. data/lib/kitchen/directions/move_solutions_to_answer_key/main.rb +14 -0
  99. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/american_government.rb +19 -0
  100. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/calculus.rb +41 -0
  101. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/uphysics.rb +63 -0
  102. data/lib/kitchen/directions/move_solutions_to_answer_key/v1.rb +34 -0
  103. data/lib/kitchen/directions/move_title_text_into_span.rb +2 -2
  104. data/lib/kitchen/document.rb +83 -13
  105. data/lib/kitchen/element.rb +20 -3
  106. data/lib/kitchen/element_base.rb +373 -63
  107. data/lib/kitchen/element_enumerator.rb +8 -0
  108. data/lib/kitchen/element_enumerator_base.rb +297 -28
  109. data/lib/kitchen/element_enumerator_factory.rb +64 -53
  110. data/lib/kitchen/element_factory.rb +27 -12
  111. data/lib/kitchen/errors.rb +5 -0
  112. data/lib/kitchen/example_element.rb +21 -6
  113. data/lib/kitchen/example_element_enumerator.rb +9 -1
  114. data/lib/kitchen/exercise_element.rb +42 -0
  115. data/lib/kitchen/exercise_element_enumerator.rb +21 -0
  116. data/lib/kitchen/figure_element.rb +36 -5
  117. data/lib/kitchen/figure_element_enumerator.rb +9 -1
  118. data/lib/kitchen/metadata_element.rb +34 -0
  119. data/lib/kitchen/metadata_element_enumerator.rb +21 -0
  120. data/lib/kitchen/mixins/block_error_if.rb +24 -4
  121. data/lib/kitchen/note_element.rb +48 -20
  122. data/lib/kitchen/note_element_enumerator.rb +9 -1
  123. data/lib/kitchen/oven.rb +66 -15
  124. data/lib/kitchen/page_element.rb +84 -14
  125. data/lib/kitchen/page_element_enumerator.rb +9 -1
  126. data/lib/kitchen/pantry.rb +28 -1
  127. data/lib/kitchen/patches/nokogiri.rb +19 -2
  128. data/lib/kitchen/patches/renderable.rb +9 -3
  129. data/lib/kitchen/patches/string.rb +8 -0
  130. data/lib/kitchen/recipe.rb +69 -32
  131. data/lib/kitchen/reference_element.rb +27 -0
  132. data/lib/kitchen/references_element_enumerator.rb +20 -0
  133. data/lib/kitchen/search_history.rb +43 -4
  134. data/lib/kitchen/search_query.rb +106 -0
  135. data/lib/kitchen/selector.rb +24 -0
  136. data/lib/kitchen/selectors/base.rb +65 -0
  137. data/lib/kitchen/selectors/standard_1.rb +21 -0
  138. data/lib/kitchen/table_element.rb +55 -7
  139. data/lib/kitchen/table_element_enumerator.rb +9 -1
  140. data/lib/kitchen/templates/eob_section_title_template.xhtml.erb +10 -0
  141. data/lib/kitchen/templates/eoc_section_title_template.xhtml.erb +10 -0
  142. data/lib/kitchen/term_element.rb +15 -4
  143. data/lib/kitchen/term_element_enumerator.rb +9 -1
  144. data/lib/kitchen/transliterations.rb +7 -5
  145. data/lib/kitchen/type_casting_element_enumerator.rb +17 -1
  146. data/lib/kitchen/unit_element.rb +45 -0
  147. data/lib/kitchen/unit_element_enumerator.rb +20 -0
  148. data/lib/kitchen/utils.rb +10 -13
  149. data/lib/kitchen/version.rb +5 -1
  150. data/lib/locales/en.yml +18 -7
  151. data/lib/locales/pl.yml +24 -0
  152. data/lib/openstax_kitchen.rb +59 -0
  153. data/openstax_kitchen.gemspec +26 -20
  154. data/tutorials/00/solution1.rb +9 -0
  155. data/tutorials/00/solution2.rb +8 -0
  156. data/tutorials/01/solution1.rb +18 -0
  157. data/tutorials/01/solution2.rb +26 -0
  158. data/tutorials/02/solution1.rb +31 -0
  159. data/tutorials/03/{solution_1.rb → solution1.rb} +6 -4
  160. data/tutorials/03/solution2.rb +18 -0
  161. data/tutorials/04/{solution_1.rb → solution1.rb} +4 -2
  162. data/tutorials/04/{solution_2.rb → solution2.rb} +6 -4
  163. data/tutorials/05/solution1.rb +11 -0
  164. data/tutorials/check_it +16 -15
  165. data/tutorials/setup_my_recipes +7 -6
  166. metadata +148 -27
  167. data/Dockerfile +0 -19
  168. data/bin/normalize +0 -79
  169. data/books/chemistry2e/bake.rb +0 -133
  170. data/docker-compose.yml +0 -12
  171. data/docker/entrypoint +0 -9
  172. data/lib/kitchen.rb +0 -57
  173. data/lib/kitchen/directions/bake_chapter_glossary.rb +0 -34
  174. data/lib/kitchen/directions/bake_exercises.rb +0 -164
  175. data/lib/kitchen/directions/bake_notes.rb +0 -58
  176. data/tutorials/00/solution_1.rb +0 -7
  177. data/tutorials/00/solution_2.rb +0 -6
  178. data/tutorials/01/solution_1.rb +0 -16
  179. data/tutorials/01/solution_2.rb +0 -24
  180. data/tutorials/02/solution_1.rb +0 -29
  181. data/tutorials/03/solution_2.rb +0 -15
  182. data/tutorials/05/solution_1.rb +0 -9
data/Dockerfile DELETED
@@ -1,19 +0,0 @@
1
- FROM ruby:2.6-slim
2
-
3
- RUN apt-get update && \
4
- apt-get install -y --no-install-recommends \
5
- git \
6
- build-essential \
7
- && rm -rf /var/lib/apt/lists/*
8
-
9
- WORKDIR /code
10
- COPY . /code/
11
-
12
- RUN gem install bundler
13
- RUN bundle install
14
-
15
- # Install other things that make development good
16
- RUN gem install solargraph
17
- RUN bundle exec yard gems
18
-
19
- ENTRYPOINT ["/code/docker/entrypoint"]
data/bin/normalize DELETED
@@ -1,79 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/inline"
4
-
5
- gemfile do
6
- gem 'nokogiri'
7
- gem 'byebug'
8
- end
9
-
10
- require 'nokogiri'
11
- require 'byebug'
12
-
13
- # In HTML attribute order doesn't matter, but to make sure our diffs are useful resort all
14
- # attributes.
15
- def sort_attributes(document)
16
- document.traverse do |child|
17
- next if child.text? || child.document?
18
- attributes = child.attributes
19
- attributes.each do |key, value|
20
- child.remove_attribute(key)
21
- end
22
- sorted_keys = attributes.keys.sort
23
- sorted_keys.each do |key|
24
- value = attributes[key].to_s
25
- child[key] = value
26
- end
27
- end
28
- end
29
-
30
- # Legacy baked docs have a few issues that I think are unintentional; clean those
31
- def clean_legacy_baked(document)
32
- document.traverse do |child|
33
- next if child.text? || child.document?
34
-
35
- # Legacy bakings of unnumbered tables include a bogus number, delete it
36
- if child.name == "table" && (child[:class] || "").include?("unnumbered")
37
- child.remove_attribute("summary")
38
- end
39
-
40
- # Sometimes there is `class=' '`, get rid of these
41
- child.attributes.each do |key, value|
42
- child.remove_attribute(key) if key == "class" && value.to_s.strip == ""
43
- end
44
- end
45
- end
46
-
47
- def mask_copied_id_numbers(document)
48
- document.traverse do |child|
49
- if child[:id]
50
- child[:id] = child[:id].gsub(/_copy_(\d+)$/,"_copy_XXX")
51
- end
52
- end
53
- end
54
-
55
- def process(input_file:, output_file:)
56
- read_and_write(input_file: input_file, output_file: output_file) do |doc|
57
- clean_legacy_baked(doc)
58
- sort_attributes(doc)
59
- mask_copied_id_numbers(doc)
60
- end
61
- end
62
-
63
- def read_and_write(input_file:, output_file:)
64
- doc = Nokogiri::XML(File.open(input_file)){|config| config.noblanks}
65
-
66
- yield(doc) if block_given?
67
-
68
- File.open(output_file, "w") do |f|
69
- f.write doc.to_xhtml(indent:2)
70
- end
71
- end
72
-
73
- ARGV.each do |input_file|
74
- output_file = input_file.gsub(/(\.\w+)\z/,'.normalized\1')
75
-
76
- process(input_file: input_file, output_file: output_file)
77
-
78
- puts "Normalized '#{input_file}' to '#{output_file}'"
79
- end
@@ -1,133 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/inline"
4
-
5
- gemfile do
6
- gem 'kitchen', path: '/Users/jps/dev/openstax/kitchen'
7
- gem 'byebug'
8
- end
9
-
10
- require "kitchen"
11
- require 'byebug'
12
-
13
- include Kitchen::Directions
14
-
15
- recipe = Kitchen::BookRecipe.new(book_short_name: :chemistry) do |doc|
16
- book = doc.book
17
-
18
- # Some stuff just goes away
19
- book.search("cnx-pi").trash
20
-
21
- # Update the preface title
22
- book.pages("$.preface").search("div[data-type='document-title']").each do |title| # TODO add title method
23
- title.replace_children(with:
24
- <<~HTML
25
- <span data-type="" itemprop="" class="os-text">#{title.text}</span>
26
- HTML
27
- )
28
- title.name = "h1"
29
- end
30
-
31
- book.chapters.each do |chapter|
32
- BakeChapterGlossary.v1(chapter: chapter, metadata_source: book.metadata)
33
- BakeChapterKeyEquations.v1(chapter: chapter, metadata_source: book.metadata)
34
- BakeChapterSummary.v1(chapter: chapter, metadata_source: book.metadata)
35
- end
36
-
37
- BakeExercises.v1(book: book)
38
- BakeChapterIntroductions.v1(book: book)
39
-
40
- book.chapters.each do |chapter|
41
- # Fix up chapter titles - TODO put this in BakeChapter
42
- heading = chapter.at("h1[2]")
43
- heading[:id] = "chapTitle#{chapter.count_in(:book)}"
44
- heading.replace_children(with:
45
- <<~HTML
46
- <span class="os-part-text">Chapter </span>
47
- <span class="os-number">#{chapter.count_in(:book)}</span>
48
- <span class="os-divider"> </span>
49
- <span data-type="" itemprop="" class="os-text">#{heading.text}</span>
50
- HTML
51
- )
52
-
53
- chapter.tables("$:not(.unnumbered)").each do |table|
54
- BakeNumberedTable.v1(table: table, number: "#{chapter.count_in(:book)}.#{table.count_in(:chapter)}")
55
- end
56
-
57
- chapter.examples.each do |example|
58
- BakeExample.v1(example: example,
59
- number: "#{chapter.count_in(:book)}.#{example.count_in(:chapter)}",
60
- title_tag: "h3")
61
- end
62
-
63
- chapter.pages("$:not(.introduction)").each do |page|
64
- page.search("div[data-type='description']").each(&:trash)
65
- page.add_class("chapter-content-module")
66
-
67
- title = page.search("div[data-type='document-title']").first
68
- title.name = "h2"
69
- title.replace_children(with:
70
- <<~HTML
71
- <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
72
- <span class="os-divider"> </span>
73
- <span data-type="" itemprop="" class="os-text">#{title.text}</span>
74
- HTML
75
- )
76
- end
77
-
78
- chapter.figures.each do |figure|
79
- BakeFigure.v1(figure: figure, number: "#{chapter.count_in(:book)}.#{figure.count_in(:chapter)}")
80
- end
81
- end
82
-
83
- book.pages("$.appendix").each do |page|
84
- appendix_letter = [*('A'..'Z')][page.count_in(:book)-1]
85
-
86
- page.figures.each do |figure|
87
- BakeFigure.v1(figure: figure, number: "#{appendix_letter}#{figure.count_in(:page)}")
88
- end
89
-
90
- page.tables("$:not(.unnumbered)").each do |table|
91
- BakeNumberedTable.v1(table: table, number: "#{appendix_letter}#{table.count_in(:page)}")
92
- end
93
-
94
- page.examples.each do |example|
95
- BakeExample.v1(example: example,
96
- number: "#{appendix_letter}#{example.count_in(:page)}",
97
- title_tag: "div")
98
- end
99
-
100
- BakeAppendix.v1(page: page, number: appendix_letter)
101
- end
102
-
103
- BakeNotes.v1(book: book)
104
- BakeStepwise.v1(book: book)
105
- BakeUnnumberedTables.v1(book: book)
106
- BakeMathInParagraph.v1(book: book)
107
- BakeIndex.v1(book: book)
108
- BakeCompositePages.v1(book: book)
109
- BakeFootnotes.v1(book: book)
110
-
111
- BakeToc.v1(book: book)
112
-
113
- # competing docs from elements - BakeLinkPlaceholders
114
- book.search("a").each do |anchor|
115
- next unless anchor.text == "[link]"
116
- id = anchor[:href][1..-1]
117
- replacement = doc.pantry(name: :link_text).get(id)
118
- if replacement.present?
119
- anchor.replace_children(with: replacement)
120
- else
121
- # TODO log a warning!
122
- puts "warning! could not find a replacement for '[link]' on an element with ID '#{id}'"
123
- end
124
- end
125
-
126
- end
127
-
128
- puts Kitchen::Oven.bake(
129
- # input_file: "collection.assembled.xhtml",
130
- input_file: "entire.collection.assembled.xhtml",
131
- recipes: recipe,
132
- output_file: "collection.kitchen.xhtml"
133
- )
data/docker-compose.yml DELETED
@@ -1,12 +0,0 @@
1
- version: '3.7'
2
- services:
3
- app:
4
- image: "openstax/kitchen"
5
- build: .
6
- volumes:
7
- - .:/code
8
- networks:
9
- - openstax
10
- networks:
11
- openstax:
12
- name: openstax
data/docker/entrypoint DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -e
3
-
4
- # uncomment this to load docker secrets into environment variables
5
- # export $(egrep -v '^#' /run/secrets/* | xargs)
6
-
7
- # exec "$@"
8
-
9
- tail -f /dev/null
data/lib/kitchen.rb DELETED
@@ -1,57 +0,0 @@
1
- require "kitchen/version"
2
-
3
- require "nokogiri"
4
- require "active_support/all"
5
-
6
- module Kitchen
7
- module Directions; end
8
- end
9
-
10
- def file_glob(relative_folder_and_extension)
11
- Dir[File.expand_path(__dir__ + "/" + relative_folder_and_extension)]
12
- end
13
-
14
- def require_all(relative_folder, file_matcher="**/*.rb")
15
- file_glob(relative_folder + "/#{file_matcher}").each{|f| require f}
16
- end
17
-
18
- require_all("kitchen/patches")
19
- require_all("kitchen/mixins")
20
-
21
- require "kitchen/selectors/base"
22
- require_all("kitchen/selectors")
23
-
24
- require "kitchen/utils"
25
- require "kitchen/transliterations"
26
- require "kitchen/errors"
27
- require "kitchen/ancestor"
28
- require "kitchen/search_history"
29
- require "kitchen/config"
30
- require "kitchen/document"
31
- require "kitchen/book_document"
32
- require "kitchen/debug/print_recipe_error"
33
- require "kitchen/recipe"
34
- require "kitchen/book_recipe"
35
- require "kitchen/oven"
36
- require "kitchen/clipboard"
37
- require "kitchen/pantry"
38
- require "kitchen/counter"
39
-
40
- require "kitchen/element_enumerator_base"
41
- require "kitchen/element_enumerator_factory"
42
- require_all("kitchen", "*enumerator.rb")
43
-
44
- require "kitchen/element_base"
45
- require_all("kitchen", "*element.rb")
46
- require "kitchen/element_factory"
47
-
48
-
49
- require_all("kitchen/directions")
50
-
51
- I18n.load_path << file_glob("/locales/*.yml")
52
-
53
-
54
- I18n.available_locales.each do |available_locale|
55
- I18n.backend.store_translations(available_locale, Kitchen::TRANSLITERATIONS)
56
- end
57
-
@@ -1,34 +0,0 @@
1
- module Kitchen
2
- module Directions
3
- module BakeChapterGlossary
4
-
5
- def self.v1(chapter:, metadata_source:)
6
- metadata_elements = metadata_source.search(%w(.authors .publishers .print-style
7
- .permissions [data-type='subject'])).copy
8
-
9
- definitions = chapter.glossaries.search("dl").cut
10
- definitions.sort_by! do |definition|
11
- [definition.first("dt").text.downcase, definition.first("dd").text.downcase]
12
- end
13
-
14
- chapter.glossaries.trash
15
-
16
- chapter.append(child:
17
- <<~HTML
18
- <div class="os-eoc os-glossary-container" data-type="composite-page" data-uuid-key="glossary">
19
- <h2 data-type="document-title">
20
- <span class="os-text">#{I18n.t(:eoc_key_terms_title)}</span>
21
- </h2>
22
- <div data-type="metadata" style="display: none;">
23
- <h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_key_terms_title)}</h1>
24
- #{metadata_elements.paste}
25
- </div>
26
- #{definitions.paste}
27
- </div>
28
- HTML
29
- ) unless definitions.none?
30
- end
31
-
32
- end
33
- end
34
- end
@@ -1,164 +0,0 @@
1
- module Kitchen
2
- module Directions
3
- module BakeExercises
4
-
5
- def self.v1(book:)
6
- metadata_elements = book.metadata.search(%w(.authors .publishers .print-style
7
- .permissions [data-type='subject'])).copy
8
-
9
- solutions_clipboards = []
10
-
11
- book.chapters.each do |chapter|
12
- exercise_clipboard = Clipboard.new
13
- solution_clipboard = Clipboard.new
14
- solutions_clipboards.push(solution_clipboard)
15
-
16
- chapter.pages("$:not(.introduction)").each do |page|
17
- exercise_section = page.exercises
18
- exercise_section.first("[data-type='title']")&.trash
19
- exercise_section_title = page.title.copy
20
- exercise_section_title.name = "h3"
21
- exercise_section_title.replace_children(with: <<~HTML
22
- <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
23
- <span class="os-divider"> </span>
24
- <span class="os-text" data-type="" itemprop="">#{exercise_section_title.children}</span>
25
- HTML
26
- )
27
-
28
- exercise_section.prepend(child:
29
- <<~HTML
30
- <a href="##{page.title.id}">
31
- #{exercise_section_title.paste}
32
- </a>
33
- HTML
34
- )
35
-
36
- exercise_section.search("[data-type='exercise']").each do |exercise|
37
- exercise.document.pantry(name: :link_text).store(
38
- "#{I18n.t(:exercise_label)} #{chapter.count_in(:book)}.#{exercise.count_in(:chapter)}",
39
- label: exercise.id
40
- )
41
-
42
- bake_exercise_in_place(exercise: exercise)
43
- exercise.first("[data-type='solution']")&.cut(to: solution_clipboard)
44
- end
45
-
46
- exercise_section.cut(to: exercise_clipboard)
47
- end
48
-
49
- chapter.append(child:
50
- <<~HTML
51
- <div class="os-eoc os-exercises-container" data-type="composite-page" data-uuid-key=".exercises">
52
- <h2 data-type="document-title">
53
- <span class="os-text">#{I18n.t(:eoc_exercises_title)}</span>
54
- </h2>
55
- <div data-type="metadata" style="display: none;">
56
- <h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_exercises_title)}</h1>
57
- #{metadata_elements.paste}
58
- </div>
59
- #{exercise_clipboard.paste}
60
- </div>
61
- HTML
62
- ) unless exercise_clipboard.none?
63
- end
64
-
65
- # Store a paste here to use at end so that uniquifyied IDs match legacy baking
66
- eob_metadata = metadata_elements.paste
67
-
68
- solutions = solutions_clipboards.map.with_index do |solution_clipboard, index|
69
- <<~HTML
70
- <div class="os-eob os-solution-container " data-type="composite-page" data-uuid-key=".solution#{index+1}">
71
- <h2 data-type="document-title">
72
- <span class="os-text">#{index+1}</span>
73
- </h2>
74
- <div data-type="metadata" style="display: none;">
75
- <h1 data-type="document-title" itemprop="name">#{index+1}</h1>
76
- #{metadata_elements.paste}
77
- </div>
78
- #{solution_clipboard.paste}
79
- </div>
80
- HTML
81
- end
82
-
83
- book.first("body").append(child:
84
- <<~HTML
85
- <div class="os-eob os-solution-container " data-type="composite-chapter" data-uuid-key=".solution">
86
- <h1 data-type="document-title" id="composite-chapter-1">
87
- <span class="os-text">#{I18n.t(:eoc_answer_key_title)}</span>
88
- </h1>
89
- <div data-type="metadata" style="display: none;">
90
- <h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_answer_key_title)}</h1>
91
- #{eob_metadata}
92
- </div>
93
- #{solutions.join("\n")}
94
- </div>
95
- HTML
96
- ) unless solutions.none?
97
- end
98
-
99
- def self.bake_exercise_in_place(exercise:)
100
- # Bake an exercise in place going from:
101
- #
102
- # <div data-type="exercise" id="exerciseId">
103
- # <div data-type="problem" id="problemId">
104
- # Problem Content
105
- # </div>
106
- # <div data-type="solution" id="solutionId">
107
- # Solution Content
108
- # </div>
109
- # </div>
110
- #
111
- # to
112
- #
113
- # <div data-type="exercise" id="exerciseId" class="os-hasSolution">
114
- # <div data-type="problem" id="problemId">
115
- # <a class="os-number" href="#exerciseId-solution">1</a>
116
- # <span class="os-divider">. </span>
117
- # <div class="os-problem-container ">
118
- # Problem Content
119
- # </div>
120
- # </div>
121
- # <div data-type="solution" id="exerciseId-solution">
122
- # <a class="os-number" href="#exerciseId">1</a>
123
- # <span class="os-divider">. </span>
124
- # <div class="os-solution-container ">
125
- # Solution Content
126
- # </div>
127
- # </div>
128
- # </div>
129
- #
130
- # If there is no solution, don't add the 'os-hasSolution' class and don't
131
- # link the number.
132
-
133
- problem = exercise.first("[data-type='problem']")
134
- solution = exercise.first("[data-type='solution']")
135
-
136
- problem_number = "<span class='os-number'>#{exercise.count_in(:chapter)}</span>"
137
-
138
- if solution.present?
139
- solution.id = "#{exercise.id}-solution"
140
-
141
- exercise.add_class("os-hasSolution")
142
- problem_number = "<a href='##{solution.id}' class='os-number' >#{exercise.count_in(:chapter)}</a>"
143
-
144
- solution.replace_children(with:
145
- <<~HTML
146
- <a class="os-number" href="##{exercise.id}">#{exercise.count_in(:chapter)}</a>
147
- <span class="os-divider">. </span>
148
- <div class="os-solution-container ">#{solution.children}</div>
149
- HTML
150
- )
151
- end
152
-
153
- problem.replace_children(with:
154
- <<~HTML
155
- #{problem_number}
156
- <span class="os-divider">. </span>
157
- <div class="os-problem-container ">#{problem.children}</div>
158
- HTML
159
- )
160
- end
161
-
162
- end
163
- end
164
- end