openstax_kitchen 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) 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 +1 -1
  6. data/.inch.yml +6 -0
  7. data/.rubocop.yml +65 -0
  8. data/CHANGELOG.md +16 -0
  9. data/Gemfile +5 -3
  10. data/Gemfile.lock +54 -5
  11. data/README.md +58 -11
  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 +16 -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 +24 -3
  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 -3
  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 +20 -1
  31. data/lib/kitchen/composite_page_element.rb +25 -2
  32. data/lib/kitchen/composite_page_element_enumerator.rb +8 -0
  33. data/lib/kitchen/config.rb +14 -7
  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.rb +10 -7
  39. data/lib/kitchen/directions/bake_chapter_introductions.rb +6 -6
  40. data/lib/kitchen/directions/bake_chapter_key_equations.rb +9 -6
  41. data/lib/kitchen/directions/bake_chapter_summary.rb +16 -13
  42. data/lib/kitchen/directions/bake_chapter_title/main.rb +11 -0
  43. data/lib/kitchen/directions/bake_chapter_title/v1.rb +24 -0
  44. data/lib/kitchen/directions/bake_composite_pages.rb +2 -2
  45. data/lib/kitchen/directions/bake_example.rb +6 -4
  46. data/lib/kitchen/directions/bake_exercises/main.rb +11 -0
  47. data/lib/kitchen/directions/bake_exercises/v1.rb +166 -0
  48. data/lib/kitchen/directions/bake_figure.rb +8 -5
  49. data/lib/kitchen/directions/bake_footnotes/main.rb +2 -2
  50. data/lib/kitchen/directions/bake_footnotes/v1.rb +4 -4
  51. data/lib/kitchen/directions/bake_index/main.rb +2 -2
  52. data/lib/kitchen/directions/bake_index/v1.rb +22 -15
  53. data/lib/kitchen/directions/bake_link_placeholders.rb +24 -0
  54. data/lib/kitchen/directions/bake_math_in_paragraph.rb +5 -3
  55. data/lib/kitchen/directions/bake_notes.rb +8 -8
  56. data/lib/kitchen/directions/bake_numbered_table/main.rb +2 -2
  57. data/lib/kitchen/directions/bake_numbered_table/v1.rb +21 -16
  58. data/lib/kitchen/directions/bake_page_abstracts.rb +14 -0
  59. data/lib/kitchen/directions/bake_preface/main.rb +11 -0
  60. data/lib/kitchen/directions/bake_preface/v1.rb +18 -0
  61. data/lib/kitchen/directions/bake_stepwise.rb +7 -7
  62. data/lib/kitchen/directions/bake_suggested_reading.rb +26 -0
  63. data/lib/kitchen/directions/bake_toc.rb +41 -22
  64. data/lib/kitchen/directions/bake_unit_title/main.rb +11 -0
  65. data/lib/kitchen/directions/bake_unit_title/v1.rb +23 -0
  66. data/lib/kitchen/directions/bake_unnumbered_tables.rb +7 -5
  67. data/lib/kitchen/directions/move_title_text_into_span.rb +2 -2
  68. data/lib/kitchen/document.rb +72 -13
  69. data/lib/kitchen/element.rb +11 -0
  70. data/lib/kitchen/element_base.rb +276 -56
  71. data/lib/kitchen/element_enumerator.rb +8 -0
  72. data/lib/kitchen/element_enumerator_base.rb +210 -28
  73. data/lib/kitchen/element_enumerator_factory.rb +59 -52
  74. data/lib/kitchen/element_factory.rb +27 -12
  75. data/lib/kitchen/errors.rb +5 -0
  76. data/lib/kitchen/example_element.rb +19 -1
  77. data/lib/kitchen/example_element_enumerator.rb +9 -1
  78. data/lib/kitchen/figure_element.rb +36 -2
  79. data/lib/kitchen/figure_element_enumerator.rb +9 -1
  80. data/lib/kitchen/metadata_element.rb +28 -0
  81. data/lib/kitchen/metadata_element_enumerator.rb +21 -0
  82. data/lib/kitchen/mixins/block_error_if.rb +24 -4
  83. data/lib/kitchen/note_element.rb +37 -7
  84. data/lib/kitchen/note_element_enumerator.rb +9 -1
  85. data/lib/kitchen/oven.rb +66 -15
  86. data/lib/kitchen/page_element.rb +62 -13
  87. data/lib/kitchen/page_element_enumerator.rb +9 -1
  88. data/lib/kitchen/pantry.rb +28 -1
  89. data/lib/kitchen/patches/nokogiri.rb +19 -2
  90. data/lib/kitchen/patches/renderable.rb +9 -3
  91. data/lib/kitchen/patches/string.rb +8 -0
  92. data/lib/kitchen/recipe.rb +38 -34
  93. data/lib/kitchen/search_history.rb +43 -4
  94. data/lib/kitchen/search_query.rb +84 -0
  95. data/lib/kitchen/selectors/base.rb +26 -0
  96. data/lib/kitchen/selectors/standard_1.rb +8 -0
  97. data/lib/kitchen/table_element.rb +54 -3
  98. data/lib/kitchen/table_element_enumerator.rb +9 -1
  99. data/lib/kitchen/term_element.rb +15 -1
  100. data/lib/kitchen/term_element_enumerator.rb +9 -1
  101. data/lib/kitchen/transliterations.rb +7 -5
  102. data/lib/kitchen/type_casting_element_enumerator.rb +17 -1
  103. data/lib/kitchen/unit_element.rb +39 -0
  104. data/lib/kitchen/unit_element_enumerator.rb +20 -0
  105. data/lib/kitchen/utils.rb +10 -13
  106. data/lib/kitchen/version.rb +5 -1
  107. data/lib/locales/en.yml +6 -0
  108. data/lib/openstax_kitchen.rb +43 -42
  109. data/openstax_kitchen.gemspec +26 -20
  110. data/tutorials/00/solution1.rb +9 -0
  111. data/tutorials/00/solution2.rb +8 -0
  112. data/tutorials/01/solution1.rb +18 -0
  113. data/tutorials/01/solution2.rb +26 -0
  114. data/tutorials/02/solution1.rb +31 -0
  115. data/tutorials/03/{solution_1.rb → solution1.rb} +6 -4
  116. data/tutorials/03/solution2.rb +18 -0
  117. data/tutorials/04/{solution_1.rb → solution1.rb} +4 -2
  118. data/tutorials/04/{solution_2.rb → solution2.rb} +6 -4
  119. data/tutorials/05/solution1.rb +11 -0
  120. data/tutorials/check_it +16 -15
  121. data/tutorials/setup_my_recipes +7 -6
  122. metadata +101 -22
  123. data/Dockerfile +0 -19
  124. data/docker-compose.yml +0 -12
  125. data/docker/entrypoint +0 -9
  126. data/lib/kitchen/directions/bake_exercises.rb +0 -164
  127. data/tutorials/00/solution_1.rb +0 -7
  128. data/tutorials/00/solution_2.rb +0 -6
  129. data/tutorials/01/solution_1.rb +0 -16
  130. data/tutorials/01/solution_2.rb +0 -24
  131. data/tutorials/02/solution_1.rb +0 -29
  132. data/tutorials/03/solution_2.rb +0 -15
  133. data/tutorials/05/solution_1.rb +0 -9
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitchen
2
4
  module Directions
3
5
  module BakeChapterIntroductions
4
-
5
6
  def self.v1(book:)
6
7
  book.chapters.each do |chapter|
7
8
  outline_items_html = chapter.pages.map do |page|
@@ -10,13 +11,13 @@ module Kitchen
10
11
  <<~HTML
11
12
  <div class="os-chapter-objective">
12
13
  <a class="os-chapter-objective" href="##{page.title[:id]}">
13
- <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)-1}</span>
14
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter) - 1}</span>
14
15
  <span class="os-divider"> </span>
15
16
  <span data-type="" itemprop="" class="os-text">#{page.title.children[0].text}</span>
16
17
  </a>
17
18
  </div>
18
19
  HTML
19
- end.join("")
20
+ end.join('')
20
21
 
21
22
  introduction_page = chapter.introduction_page
22
23
 
@@ -24,7 +25,7 @@ module Kitchen
24
25
  introduction_page.search("div[data-type='abstract']").trash
25
26
 
26
27
  title = introduction_page.title.cut
27
- title.name = "h2"
28
+ title.name = 'h2'
28
29
  MoveTitleTextIntoSpan.v1(title: title)
29
30
 
30
31
  intro_content = introduction_page.search("> :not([data-type='metadata']):not(figure)").cut
@@ -33,7 +34,7 @@ module Kitchen
33
34
  <<~HTML
34
35
  <div class="intro-body">
35
36
  <div class="os-chapter-outline">
36
- <h3 class="os-title">Chapter Outline</h3>
37
+ <h3 class="os-title">#{I18n.t(:chapter_outline)}</h3>
37
38
  #{outline_items_html}
38
39
  </div>
39
40
  <div class="intro-text">
@@ -52,7 +53,6 @@ module Kitchen
52
53
  something_with_selectors.selectors.title_in_introduction_page =
53
54
  ".intro-text > [data-type='document-title']"
54
55
  end
55
-
56
56
  end
57
57
  end
58
58
  end
@@ -1,14 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitchen
2
4
  module Directions
5
+ # Bake directions for eoc key equations
6
+ #
3
7
  module BakeChapterKeyEquations
4
-
5
8
  def self.v1(chapter:, metadata_source:)
6
- metadata_elements = metadata_source.search(%w(.authors .publishers .print-style
7
- .permissions [data-type='subject'])).copy
9
+ metadata_elements = metadata_source.children_to_keep.copy
8
10
 
9
- chapter.key_equations.search("h3").trash
11
+ chapter.key_equations.search('h3').trash
10
12
  key_equations = chapter.key_equations.cut
11
13
 
14
+ return if key_equations.none?
15
+
12
16
  chapter.append(child:
13
17
  <<~HTML
14
18
  <div class="os-eoc os-key-equations-container" data-type="composite-page" data-uuid-key=".key-equations">
@@ -22,9 +26,8 @@ module Kitchen
22
26
  #{key_equations.paste}
23
27
  </div>
24
28
  HTML
25
- ) unless key_equations.none?
29
+ )
26
30
  end
27
-
28
31
  end
29
32
  end
30
33
  end
@@ -1,24 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitchen
2
4
  module Directions
5
+ # Bake directions for eoc summary
6
+ #
3
7
  module BakeChapterSummary
4
-
5
8
  def self.v1(chapter:, metadata_source:)
6
- metadata_elements = metadata_source.search(%w(.authors .publishers .print-style
7
- .permissions [data-type='subject'])).copy
9
+ metadata_elements = metadata_source.children_to_keep.copy
8
10
 
9
11
  summaries = Clipboard.new
10
12
 
11
- # TODO include specific page types somehow without writing it out
12
- chapter.pages("$:not(.introduction)").each do |page|
13
+ # TODO: include specific page types somehow without writing it out
14
+ chapter.pages('$:not(.introduction)').each do |page|
13
15
  summary = page.summary
14
- summary.first("[data-type='title']").trash # get rid of old title
16
+ summary.first("[data-type='title']")&.trash # get rid of old title if exists
15
17
  summary_title = page.title.copy
16
- summary_title.name = "h3"
18
+ summary_title.name = 'h3'
17
19
  summary_title.replace_children(with: <<~HTML
18
- <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
19
- <span class="os-divider"> </span>
20
- <span class="os-text" data-type="" itemprop="">#{summary_title.children}</span>
21
- HTML
20
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
21
+ <span class="os-divider"> </span>
22
+ <span class="os-text" data-type="" itemprop="">#{summary_title.children}</span>
23
+ HTML
22
24
  )
23
25
 
24
26
  summary.prepend(child:
@@ -31,6 +33,8 @@ module Kitchen
31
33
  summary.cut(to: summaries)
32
34
  end
33
35
 
36
+ return if summaries.none?
37
+
34
38
  chapter.append(child:
35
39
  <<~HTML
36
40
  <div class="os-eoc os-summary-container" data-type="composite-page" data-uuid-key=".summary">
@@ -44,9 +48,8 @@ module Kitchen
44
48
  #{summaries.paste}
45
49
  </div>
46
50
  HTML
47
- ) unless summaries.none?
51
+ )
48
52
  end
49
-
50
53
  end
51
54
  end
52
55
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeChapterTitle
6
+ def self.v1(book:)
7
+ V1.new.bake(book: book)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeChapterTitle
4
+ class V1
5
+ def bake(book:)
6
+ book.chapters.each do |chapter|
7
+ fix_up_chapter_title(chapter: chapter)
8
+ end
9
+ end
10
+
11
+ def fix_up_chapter_title(chapter:)
12
+ heading = chapter.at('h1[2]')
13
+ heading[:id] = "chapTitle#{chapter.count_in(:book)}"
14
+ heading.replace_children(with:
15
+ <<~HTML
16
+ <span class="os-part-text">#{I18n.t(:chapter)} </span>
17
+ <span class="os-number">#{chapter.count_in(:book)}</span>
18
+ <span class="os-divider"> </span>
19
+ <span data-type="" itemprop="" class="os-text">#{heading.text}</span>
20
+ HTML
21
+ )
22
+ end
23
+ end
24
+ end
@@ -1,13 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitchen
2
4
  module Directions
3
5
  module BakeCompositePages
4
-
5
6
  def self.v1(book:)
6
7
  book.search("[data-type='composite-page']").each do |page|
7
8
  page.id = "composite-page-#{page.count_in(:book)}"
8
9
  end
9
10
  end
10
-
11
11
  end
12
12
  end
13
13
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitchen
2
4
  module Directions
3
5
  module BakeExample
4
-
5
6
  def self.v1(example:, number:, title_tag:)
6
7
  example.replace_children(with:
7
8
  <<~HTML
@@ -21,11 +22,12 @@ module Kitchen
21
22
  HTML
22
23
  )
23
24
 
24
- example.document.pantry(name: :link_text).store "#{I18n.t(:example_label)} #{number}", label: example.id
25
+ example.document
26
+ .pantry(name: :link_text)
27
+ .store("#{I18n.t(:example_label)} #{number}", label: example.id)
25
28
 
26
- example.titles.each {|title| title.name = "h4"}
29
+ example.titles.each { |title| title.name = 'h4' }
27
30
  end
28
-
29
31
  end
30
32
  end
31
33
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Directions
5
+ module BakeExercises
6
+ def self.v1(book:)
7
+ V1.new.bake(book: book)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen::Directions::BakeExercises
4
+ class V1
5
+ def bake(book:)
6
+ metadata_elements = book.metadata.children_to_keep.copy
7
+
8
+ solutions_clipboards = []
9
+
10
+ book.chapters.each do |chapter|
11
+ exercise_clipboard = Kitchen::Clipboard.new
12
+ solution_clipboard = Kitchen::Clipboard.new
13
+ solutions_clipboards.push(solution_clipboard)
14
+
15
+ chapter.pages('$:not(.introduction)').each do |page|
16
+ exercise_section = page.exercises
17
+ exercise_section.first("[data-type='title']")&.trash
18
+ exercise_section_title = page.title.copy
19
+ exercise_section_title.name = 'h3'
20
+ exercise_section_title.replace_children(with: <<~HTML
21
+ <span class="os-number">#{chapter.count_in(:book)}.#{page.count_in(:chapter)}</span>
22
+ <span class="os-divider"> </span>
23
+ <span class="os-text" data-type="" itemprop="">#{exercise_section_title.children}</span>
24
+ HTML
25
+ )
26
+
27
+ exercise_section.prepend(child:
28
+ <<~HTML
29
+ <a href="##{page.title.id}">
30
+ #{exercise_section_title.paste}
31
+ </a>
32
+ HTML
33
+ )
34
+
35
+ exercise_section.search("[data-type='exercise']").each do |exercise|
36
+ exercise.document.pantry(name: :link_text).store(
37
+ "#{I18n.t(:exercise_label)} #{chapter.count_in(:book)}.#{exercise.count_in(:chapter)}",
38
+ label: exercise.id
39
+ )
40
+
41
+ bake_exercise_in_place(exercise: exercise)
42
+ exercise.first("[data-type='solution']")&.cut(to: solution_clipboard)
43
+ end
44
+
45
+ exercise_section.cut(to: exercise_clipboard)
46
+ end
47
+
48
+ next if exercise_clipboard.none?
49
+
50
+ chapter.append(child:
51
+ <<~HTML
52
+ <div class="os-eoc os-exercises-container" data-type="composite-page" data-uuid-key=".exercises">
53
+ <h2 data-type="document-title">
54
+ <span class="os-text">#{I18n.t(:eoc_exercises_title)}</span>
55
+ </h2>
56
+ <div data-type="metadata" style="display: none;">
57
+ <h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_exercises_title)}</h1>
58
+ #{metadata_elements.paste}
59
+ </div>
60
+ #{exercise_clipboard.paste}
61
+ </div>
62
+ HTML
63
+ )
64
+ end
65
+
66
+ # Store a paste here to use at end so that uniquifyied IDs match legacy baking
67
+ eob_metadata = metadata_elements.paste
68
+
69
+ solutions = solutions_clipboards.map.with_index do |solution_clipboard, index|
70
+ <<~HTML
71
+ <div class="os-eob os-solution-container " data-type="composite-page" data-uuid-key=".solution#{index + 1}">
72
+ <h2 data-type="document-title">
73
+ <span class="os-text">#{I18n.t(:chapter)} #{index + 1}</span>
74
+ </h2>
75
+ <div data-type="metadata" style="display: none;">
76
+ <h1 data-type="document-title" itemprop="name">#{I18n.t(:chapter)} #{index + 1}</h1>
77
+ #{metadata_elements.paste}
78
+ </div>
79
+ #{solution_clipboard.paste}
80
+ </div>
81
+ HTML
82
+ end
83
+
84
+ return if solutions.none?
85
+
86
+ book.first('body').append(child:
87
+ <<~HTML
88
+ <div class="os-eob os-solution-container " data-type="composite-chapter" data-uuid-key=".solution">
89
+ <h1 data-type="document-title" id="composite-chapter-1">
90
+ <span class="os-text">#{I18n.t(:eoc_answer_key_title)}</span>
91
+ </h1>
92
+ <div data-type="metadata" style="display: none;">
93
+ <h1 data-type="document-title" itemprop="name">#{I18n.t(:eoc_answer_key_title)}</h1>
94
+ #{eob_metadata}
95
+ </div>
96
+ #{solutions.join("\n")}
97
+ </div>
98
+ HTML
99
+ )
100
+ end
101
+
102
+ def bake_exercise_in_place(exercise:)
103
+ # Bake an exercise in place going from:
104
+ #
105
+ # <div data-type="exercise" id="exerciseId">
106
+ # <div data-type="problem" id="problemId">
107
+ # Problem Content
108
+ # </div>
109
+ # <div data-type="solution" id="solutionId">
110
+ # Solution Content
111
+ # </div>
112
+ # </div>
113
+ #
114
+ # to
115
+ #
116
+ # <div data-type="exercise" id="exerciseId" class="os-hasSolution">
117
+ # <div data-type="problem" id="problemId">
118
+ # <a class="os-number" href="#exerciseId-solution">1</a>
119
+ # <span class="os-divider">. </span>
120
+ # <div class="os-problem-container ">
121
+ # Problem Content
122
+ # </div>
123
+ # </div>
124
+ # <div data-type="solution" id="exerciseId-solution">
125
+ # <a class="os-number" href="#exerciseId">1</a>
126
+ # <span class="os-divider">. </span>
127
+ # <div class="os-solution-container ">
128
+ # Solution Content
129
+ # </div>
130
+ # </div>
131
+ # </div>
132
+ #
133
+ # If there is no solution, don't add the 'os-hasSolution' class and don't
134
+ # link the number.
135
+
136
+ problem = exercise.first("[data-type='problem']")
137
+ solution = exercise.first("[data-type='solution']")
138
+
139
+ problem_number = "<span class='os-number'>#{exercise.count_in(:chapter)}</span>"
140
+
141
+ if solution.present?
142
+ solution.id = "#{exercise.id}-solution"
143
+
144
+ exercise.add_class('os-hasSolution')
145
+ problem_number =
146
+ "<a href='##{solution.id}' class='os-number' >#{exercise.count_in(:chapter)}</a>"
147
+
148
+ solution.replace_children(with:
149
+ <<~HTML
150
+ <a class="os-number" href="##{exercise.id}">#{exercise.count_in(:chapter)}</a>
151
+ <span class="os-divider">. </span>
152
+ <div class="os-solution-container ">#{solution.children}</div>
153
+ HTML
154
+ )
155
+ end
156
+
157
+ problem.replace_children(with:
158
+ <<~HTML
159
+ #{problem_number}
160
+ <span class="os-divider">. </span>
161
+ <div class="os-problem-container ">#{problem.children}</div>
162
+ HTML
163
+ )
164
+ end
165
+ end
166
+ end
@@ -1,21 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitchen
2
4
  module Directions
3
5
  module BakeFigure
4
-
5
6
  def self.v1(figure:, number:)
6
- figure.wrap(%Q(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
7
+ figure.wrap(%(<div class="os-figure#{' has-splash' if figure.has_class?('splash')}">))
7
8
 
8
- figure.document.pantry(name: :link_text).store "Figure #{number}", label: figure.id
9
+ figure.document.pantry(name: :link_text).store "#{I18n.t(:figure)} #{number}", label: figure.id
10
+ title = figure.title&.cut
9
11
 
10
12
  caption = figure.caption&.cut
11
13
  figure.append(sibling:
12
14
  <<~HTML
13
15
  <div class="os-caption-container">
14
- <span class="os-title-label">Figure </span>
16
+ <span class="os-title-label">#{I18n.t(:figure)} </span>
15
17
  <span class="os-number">#{number}</span>
16
18
  <span class="os-divider"> </span>
19
+ #{"<span class=\"os-title\" data-type=\"title\" id=\"#{title.id}\">#{title.children}</span>" if title}
17
20
  <span class="os-divider"> </span>
18
- #{'<span class="os-caption">' + caption.children.to_s + '</span>'if caption}
21
+ #{"<span class=\"os-caption\">#{caption.children}</span>" if caption}
19
22
  </div>
20
23
  HTML
21
24
  )
@@ -1,11 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kitchen
2
4
  module Directions
3
5
  module BakeFootnotes
4
-
5
6
  def self.v1(book:)
6
7
  V1.new.bake(book: book)
7
8
  end
8
-
9
9
  end
10
10
  end
11
11
  end