openstax_kitchen 3.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/CHANGELOG.md +64 -0
  4. data/Gemfile.lock +20 -14
  5. data/README.md +16 -0
  6. data/codecov.yaml +1 -0
  7. data/docker/ci +0 -1
  8. data/lib/kitchen/book_document.rb +1 -1
  9. data/lib/kitchen/book_element.rb +16 -2
  10. data/lib/kitchen/chapter_element.rb +10 -13
  11. data/lib/kitchen/chapter_element_enumerator.rb +1 -1
  12. data/lib/kitchen/composite_chapter_element.rb +7 -11
  13. data/lib/kitchen/composite_chapter_element_enumerator.rb +21 -0
  14. data/lib/kitchen/composite_page_element.rb +15 -10
  15. data/lib/kitchen/composite_page_element_enumerator.rb +1 -1
  16. data/lib/kitchen/config.rb +14 -0
  17. data/lib/kitchen/directions/bake_chapter_glossary/main.rb +18 -0
  18. data/lib/kitchen/directions/bake_chapter_glossary/v1.rb +30 -0
  19. data/lib/kitchen/directions/bake_chapter_introductions.rb +1 -1
  20. data/lib/kitchen/directions/bake_chapter_key_concepts/main.rb +7 -2
  21. data/lib/kitchen/directions/bake_chapter_key_concepts/v1.rb +12 -7
  22. data/lib/kitchen/directions/bake_chapter_key_equations.rb +26 -21
  23. data/lib/kitchen/directions/bake_chapter_references/main.rb +16 -0
  24. data/lib/kitchen/directions/bake_chapter_references/v1.rb +35 -0
  25. data/lib/kitchen/directions/bake_chapter_summary.rb +48 -42
  26. data/lib/kitchen/directions/bake_composite_chapters.rb +1 -1
  27. data/lib/kitchen/directions/bake_composite_pages.rb +1 -1
  28. data/lib/kitchen/directions/bake_equations.rb +14 -4
  29. data/lib/kitchen/directions/bake_example.rb +5 -1
  30. data/lib/kitchen/directions/bake_figure.rb +1 -1
  31. data/lib/kitchen/directions/bake_first_elements.rb +22 -0
  32. data/lib/kitchen/directions/bake_footnotes/v1.rb +2 -1
  33. data/lib/kitchen/directions/bake_free_response/free_response.xhtml.erb +10 -0
  34. data/lib/kitchen/directions/bake_free_response/main.rb +11 -0
  35. data/lib/kitchen/directions/bake_free_response/v1.rb +29 -0
  36. data/lib/kitchen/directions/bake_further_research.rb +59 -0
  37. data/lib/kitchen/directions/bake_index/v1.rb +36 -26
  38. data/lib/kitchen/directions/bake_link_placeholders.rb +1 -1
  39. data/lib/kitchen/directions/bake_notes/bake_note_subtitle.rb +4 -0
  40. data/lib/kitchen/directions/bake_notes/bake_numbered_notes.rb +9 -21
  41. data/lib/kitchen/directions/bake_numbered_exercise/main.rb +6 -2
  42. data/lib/kitchen/directions/bake_numbered_exercise/v1.rb +25 -12
  43. data/lib/kitchen/directions/bake_numbered_table/v1.rb +1 -8
  44. data/lib/kitchen/directions/bake_page_abstracts.rb +1 -1
  45. data/lib/kitchen/directions/bake_references/main.rb +16 -0
  46. data/lib/kitchen/directions/bake_references/v1.rb +48 -0
  47. data/lib/kitchen/directions/bake_suggested_reading.rb +5 -0
  48. data/lib/kitchen/directions/bake_toc.rb +4 -2
  49. data/lib/kitchen/directions/{bake_book_answer_key → book_answer_key_container}/eob_solutions_container.xhtml.erb +0 -0
  50. data/lib/kitchen/directions/{bake_book_answer_key → book_answer_key_container}/main.rb +1 -1
  51. data/lib/kitchen/directions/{bake_book_answer_key → book_answer_key_container}/v1.rb +2 -2
  52. data/lib/kitchen/directions/{bake_chapter_review → chapter_review_container}/chapter_review.xhtml.erb +0 -0
  53. data/lib/kitchen/directions/{bake_chapter_review → chapter_review_container}/main.rb +1 -1
  54. data/lib/kitchen/directions/{bake_chapter_review → chapter_review_container}/v1.rb +2 -2
  55. data/lib/kitchen/directions/eoc_section_title_link_snippet.rb +1 -1
  56. data/lib/kitchen/directions/move_exercises_to_eoc/main.rb +27 -0
  57. data/lib/kitchen/directions/{bake_chapter_review_exercises → move_exercises_to_eoc}/v1.rb +8 -10
  58. data/lib/kitchen/directions/{bake_chapter_review_exercises → move_exercises_to_eoc}/v2.rb +8 -9
  59. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/main.rb +1 -1
  60. data/lib/kitchen/directions/move_solutions_to_answer_key/strategies/american_government.rb +19 -0
  61. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/strategies/calculus.rb +1 -1
  62. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/strategies/uphysics.rb +7 -5
  63. data/lib/kitchen/directions/{bake_chapter_answer_key → move_solutions_to_answer_key}/v1.rb +3 -1
  64. data/lib/kitchen/document.rb +20 -42
  65. data/lib/kitchen/element.rb +9 -3
  66. data/lib/kitchen/element_base.rb +93 -21
  67. data/lib/kitchen/element_enumerator_base.rb +33 -2
  68. data/lib/kitchen/element_enumerator_factory.rb +28 -12
  69. data/lib/kitchen/element_factory.rb +3 -3
  70. data/lib/kitchen/example_element.rb +8 -11
  71. data/lib/kitchen/example_element_enumerator.rb +1 -1
  72. data/lib/kitchen/exercise_element.rb +7 -10
  73. data/lib/kitchen/exercise_element_enumerator.rb +1 -1
  74. data/lib/kitchen/figure_element.rb +8 -11
  75. data/lib/kitchen/figure_element_enumerator.rb +1 -1
  76. data/lib/kitchen/id_tracker.rb +68 -0
  77. data/lib/kitchen/metadata_element.rb +8 -2
  78. data/lib/kitchen/metadata_element_enumerator.rb +1 -1
  79. data/lib/kitchen/note_element.rb +8 -11
  80. data/lib/kitchen/note_element_enumerator.rb +1 -1
  81. data/lib/kitchen/oven.rb +5 -1
  82. data/lib/kitchen/page_element.rb +25 -9
  83. data/lib/kitchen/page_element_enumerator.rb +1 -1
  84. data/lib/kitchen/patches/i18n.rb +34 -0
  85. data/lib/kitchen/patches/nokogiri.rb +55 -0
  86. data/lib/kitchen/patches/nokogiri_profiling.rb +60 -0
  87. data/lib/kitchen/reference_element.rb +27 -0
  88. data/lib/kitchen/references_element_enumerator.rb +20 -0
  89. data/lib/kitchen/search_query.rb +31 -3
  90. data/lib/kitchen/selector.rb +25 -0
  91. data/lib/kitchen/selectors/base.rb +39 -0
  92. data/lib/kitchen/selectors/standard_1.rb +13 -0
  93. data/lib/kitchen/table_element.rb +8 -11
  94. data/lib/kitchen/table_element_enumerator.rb +1 -1
  95. data/lib/kitchen/templates/eob_section_title_template.xhtml.erb +10 -0
  96. data/lib/kitchen/templates/eoc_section_title_template.xhtml.erb +10 -0
  97. data/lib/kitchen/term_element.rb +5 -8
  98. data/lib/kitchen/term_element_enumerator.rb +1 -1
  99. data/lib/kitchen/unit_element.rb +13 -7
  100. data/lib/kitchen/unit_element_enumerator.rb +1 -1
  101. data/lib/kitchen/version.rb +1 -1
  102. data/lib/locales/en.yml +3 -0
  103. data/lib/locales/es.yml +32 -0
  104. data/lib/openstax_kitchen.rb +2 -5
  105. data/openstax_kitchen.gemspec +1 -0
  106. metadata +51 -23
  107. data/lib/kitchen/directions/bake_chapter_glossary.rb +0 -39
  108. data/lib/kitchen/directions/bake_chapter_key_concepts/key_concepts.xhtml.erb +0 -16
  109. data/lib/kitchen/directions/bake_chapter_review_exercises/main.rb +0 -15
  110. data/lib/kitchen/directions/bake_chapter_review_exercises/review_exercises.xhtml.erb +0 -10
  111. data/lib/kitchen/directions/bake_exercises/main.rb +0 -12
  112. data/lib/kitchen/directions/bake_exercises/v1.rb +0 -169
  113. data/lib/kitchen/directions/bake_notes/bake_notes.rb +0 -48
  114. data/lib/kitchen/directions/bake_problem_first_elements.rb +0 -16
  115. data/lib/kitchen/transliterations.rb +0 -21
@@ -84,7 +84,30 @@ module Kitchen
84
84
  #
85
85
  def composite_pages(css_or_xpath=nil, only: nil, except: nil)
86
86
  block_error_if(block_given?)
87
- chain_to(CompositePageElementEnumerator, css_or_xpath: css_or_xpath, only: only, except: except)
87
+ chain_to(CompositePageElementEnumerator,
88
+ css_or_xpath: css_or_xpath,
89
+ only: only,
90
+ except: except)
91
+ end
92
+
93
+ # Returns an enumerator that iterates through composite chapters within the scope of this enumerator
94
+ #
95
+ # @param css_or_xpath [String] additional selectors to further narrow the element iterated over;
96
+ # a "$" in this argument will be replaced with the default selector for the element being
97
+ # iterated over.
98
+ # @param only [Symbol, Callable] the name of a method to call on an element or a
99
+ # lambda or proc that accepts an element; elements will only be included in the
100
+ # search results if the method or callable returns true
101
+ # @param except [Symbol, Callable] the name of a method to call on an element or a
102
+ # lambda or proc that accepts an element; elements will not be included in the
103
+ # search results if the method or callable returns false
104
+ #
105
+ def composite_chapters(css_or_xpath=nil, only: nil, except: nil)
106
+ block_error_if(block_given?)
107
+ chain_to(CompositeChapterElementEnumerator,
108
+ css_or_xpath: css_or_xpath,
109
+ only: only,
110
+ except: except)
88
111
  end
89
112
 
90
113
  # Returns an enumerator that iterates through pages that arent the introduction page within the scope of this enumerator
@@ -218,11 +241,19 @@ module Kitchen
218
241
  except: except)
219
242
  end
220
243
 
221
- # Returns an enumerator that iterates through exercises within the scope of this enumerator
244
+ # Returns an enumerator that iterates through references within the scope of this enumerator
222
245
  #
223
246
  # @param css_or_xpath [String] additional selectors to further narrow the element iterated over;
224
247
  # a "$" in this argument will be replaced with the default selector for the element being
225
248
  # iterated over.
249
+ #
250
+ def references(css_or_xpath=nil)
251
+ block_error_if(block_given?)
252
+ chain_to(ReferenceElementEnumerator, css_or_xpath: css_or_xpath)
253
+ end
254
+
255
+ # Returns an enumerator that iterates through exercises within the scope of this enumerator
256
+ #
226
257
  # @param only [Symbol, Callable] the name of a method to call on an element or a
227
258
  # lambda or proc that accepts an element; elements will only be included in the
228
259
  # search results if the method or callable returns true
@@ -12,8 +12,11 @@ module Kitchen
12
12
 
13
13
  # Creates a new instance
14
14
  #
15
- # @param default_css_or_xpath [String] The selectors to substitute for the "$" character
16
- # when this factory is used to build an enumerator.
15
+ # @param default_css_or_xpath [String, Proc, Symbol] The selectors to substitute for the "$" character
16
+ # when this factory is used to build an enumerator. A string argument is used literally. A proc
17
+ # is eventually called given the document's Config object (for accessing selectors). A symbol
18
+ # is interpreted as the name of a selector and is called on the document's Config object's
19
+ # selectors object. The easiest way to get a Proc is to pass `Selector.named(:name_of_selector)`
17
20
  # @param sub_element_class [ElementBase] The element class to use for what the enumerator finds.
18
21
  # @param enumerator_class [ElementEnumeratorBase] The enumerator class to return
19
22
  # @param detect_sub_element_class [Boolean] If true, infers the sub_element_class from the node
@@ -36,14 +39,22 @@ module Kitchen
36
39
  # @return [ElementEnumeratorBase] actually returns the concrete enumerator class
37
40
  # given to the factory in its constructor.
38
41
  #
39
- def build_within(enumerator_or_element, search_query: SearchQuery.new)
40
- search_query.apply_default_css_or_xpath_and_normalize(default_css_or_xpath)
41
-
42
+ def build_within(enumerator_or_element, search_query: SearchQuery.new, reload: false)
42
43
  case enumerator_or_element
43
44
  when ElementBase
44
- build_within_element(enumerator_or_element, search_query: search_query)
45
+ build_within_element(enumerator_or_element,
46
+ search_query: search_query,
47
+ reload: reload)
45
48
  when ElementEnumeratorBase
46
- build_within_other_enumerator(enumerator_or_element, search_query: search_query)
49
+ if enumerator_class != ElementEnumerator && !search_query.expects_substitution?
50
+ raise "Query #{search_query} is missing the substitution character ('$') but " \
51
+ "is run with an enumerator #{enumerator_class.name} that has its own " \
52
+ "selectors for substitution."
53
+ end
54
+
55
+ build_within_other_enumerator(enumerator_or_element,
56
+ search_query: search_query,
57
+ reload: reload)
47
58
  end
48
59
  end
49
60
 
@@ -55,7 +66,7 @@ module Kitchen
55
66
  #
56
67
  def or_with(other_factory)
57
68
  self.class.new(
58
- default_css_or_xpath: "#{default_css_or_xpath}, #{other_factory.default_css_or_xpath}",
69
+ default_css_or_xpath: [default_css_or_xpath, other_factory.default_css_or_xpath],
59
70
  enumerator_class: TypeCastingElementEnumerator,
60
71
  detect_sub_element_class: true
61
72
  )
@@ -63,7 +74,10 @@ module Kitchen
63
74
 
64
75
  protected
65
76
 
66
- def build_within_element(element, search_query:)
77
+ def build_within_element(element, search_query:, reload:)
78
+ search_query.apply_default_css_or_xpath_and_normalize(default_css_or_xpath,
79
+ config: element.config)
80
+
67
81
  enumerator_class.new(search_query: search_query) do |block|
68
82
  grand_ancestors = element.ancestors
69
83
  parent_ancestor = Ancestor.new(element)
@@ -73,7 +87,7 @@ module Kitchen
73
87
  # below, the counts are correct.
74
88
  element.uncount(search_query)
75
89
 
76
- element.raw.search(*search_query.css_or_xpath).each do |sub_node|
90
+ element.raw_search(*search_query.css_or_xpath, reload: reload).each do |sub_node|
77
91
  sub_element = ElementFactory.build_from_node(
78
92
  node: sub_node,
79
93
  document: element.document,
@@ -101,13 +115,15 @@ module Kitchen
101
115
  end
102
116
  end
103
117
 
104
- def build_within_other_enumerator(other_enumerator, search_query:)
118
+ def build_within_other_enumerator(other_enumerator, search_query:, reload:)
105
119
  # Return a new enumerator instance that internally iterates over `other_enumerator`
106
120
  # running a new enumerator for each element returned by that other enumerator.
107
121
  enumerator_class.new(search_query: search_query,
108
122
  upstream_enumerator: other_enumerator) do |block|
109
123
  other_enumerator.each do |element|
110
- build_within_element(element, search_query: search_query).each do |sub_element|
124
+ build_within_element(element,
125
+ search_query: search_query,
126
+ reload: reload).each do |sub_element|
111
127
  block.yield(sub_element)
112
128
  end
113
129
  end
@@ -25,7 +25,7 @@ module Kitchen
25
25
  element_class: nil,
26
26
  default_short_type: nil,
27
27
  detect_element_class: false)
28
- element_class ||= detect_element_class ? specific_element_class_for_node(node) : Element
28
+ element_class ||= detect_element_class ? find_element_class(node, document.config) : Element
29
29
 
30
30
  if element_class == Element
31
31
  element_class.new(node: node,
@@ -37,9 +37,9 @@ module Kitchen
37
37
  end
38
38
  end
39
39
 
40
- def self.specific_element_class_for_node(node)
40
+ def self.find_element_class(node, config)
41
41
  ELEMENT_CLASSES.find do |klass|
42
- klass.is_the_element_class_for?(node)
42
+ klass.is_the_element_class_for?(node, config: config)
43
43
  end || Element
44
44
  end
45
45
 
@@ -13,8 +13,14 @@ module Kitchen
13
13
  def initialize(node:, document: nil)
14
14
  super(node: node,
15
15
  document: document,
16
- enumerator_class: ExampleElementEnumerator,
17
- short_type: :example)
16
+ enumerator_class: ExampleElementEnumerator)
17
+ end
18
+
19
+ # Returns the short type
20
+ # @return [Symbol]
21
+ #
22
+ def self.short_type
23
+ :example
18
24
  end
19
25
 
20
26
  # Returns the an enumerator for titles.
@@ -25,14 +31,5 @@ module Kitchen
25
31
  search("span[data-type='title']")
26
32
  end
27
33
 
28
- # Returns true if this class represents the element for the given node
29
- #
30
- # @param node [Nokogiri::XML::Node] the underlying node
31
- # @return [Boolean]
32
- #
33
- def self.is_the_element_class_for?(node)
34
- node['data-type'] == 'example'
35
- end
36
-
37
34
  end
38
35
  end
@@ -11,7 +11,7 @@ module Kitchen
11
11
  #
12
12
  def self.factory
13
13
  ElementEnumeratorFactory.new(
14
- default_css_or_xpath: "div[data-type='example']", # TODO: element.document.selectors.example
14
+ default_css_or_xpath: Selector.named(:example),
15
15
  sub_element_class: ExampleElement,
16
16
  enumerator_class: self
17
17
  )
@@ -13,17 +13,14 @@ module Kitchen
13
13
  def initialize(node:, document: nil)
14
14
  super(node: node,
15
15
  document: document,
16
- enumerator_class: ExerciseElementEnumerator,
17
- short_type: :exercise)
16
+ enumerator_class: ExerciseElementEnumerator)
18
17
  end
19
18
 
20
- # Returns true if this class represents the element for the given node
19
+ # Returns the short type
20
+ # @return [Symbol]
21
21
  #
22
- # @param node [Nokogiri::XML::Node] the underlying node
23
- # @return [Boolean]
24
- #
25
- def self.is_the_element_class_for?(node)
26
- node['data-type'] == 'exercise'
22
+ def self.short_type
23
+ :exercise
27
24
  end
28
25
 
29
26
  # Returns the enumerator for problem.
@@ -31,7 +28,7 @@ module Kitchen
31
28
  # @return ElementEnumerator
32
29
  #
33
30
  def problem
34
- first("[data-type='problem']")
31
+ first("div[data-type='problem']")
35
32
  end
36
33
 
37
34
  # Returns the enumerator for solution.
@@ -39,7 +36,7 @@ module Kitchen
39
36
  # @return ElementEnumerator
40
37
  #
41
38
  def solution
42
- first("[data-type='solution']")
39
+ first("div[data-type='solution']")
43
40
  end
44
41
  end
45
42
  end
@@ -11,7 +11,7 @@ module Kitchen
11
11
  #
12
12
  def self.factory
13
13
  ElementEnumeratorFactory.new(
14
- default_css_or_xpath: "div[data-type='exercise']", # TODO: element.document.selectors.exercise
14
+ default_css_or_xpath: Selector.named(:exercise),
15
15
  sub_element_class: ExerciseElement,
16
16
  enumerator_class: self
17
17
  )
@@ -13,8 +13,14 @@ module Kitchen
13
13
  def initialize(node:, document: nil)
14
14
  super(node: node,
15
15
  document: document,
16
- enumerator_class: FigureElementEnumerator,
17
- short_type: :figure)
16
+ enumerator_class: FigureElementEnumerator)
17
+ end
18
+
19
+ # Returns the short type
20
+ # @return [Symbol]
21
+ #
22
+ def self.short_type
23
+ :figure
18
24
  end
19
25
 
20
26
  # Returns the caption element
@@ -41,14 +47,5 @@ module Kitchen
41
47
  parent.name == 'figure'
42
48
  end
43
49
 
44
- # Returns true if this class represents the element for the given node
45
- #
46
- # @param node [Nokogiri::XML::Node] the underlying node
47
- # @return [Boolean]
48
- #
49
- def self.is_the_element_class_for?(node)
50
- node.name == 'figure'
51
- end
52
-
53
50
  end
54
51
  end
@@ -11,7 +11,7 @@ module Kitchen
11
11
  #
12
12
  def self.factory
13
13
  ElementEnumeratorFactory.new(
14
- default_css_or_xpath: 'figure', # TODO: get from config?
14
+ default_css_or_xpath: Selector.named(:figure),
15
15
  sub_element_class: FigureElement,
16
16
  enumerator_class: self
17
17
  )
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ # A class to track and modify duplicate IDs in a document
5
+ #
6
+ class IdTracker
7
+
8
+ def initialize
9
+ @id_data = Hash.new { |hash, key| hash[key] = { count: 0, last_pasted: false } }
10
+ @id_copy_suffix = '_copy_'
11
+ end
12
+
13
+ # Keeps track that an element with the given ID has been copied. When such
14
+ # elements are pasted, this information is used to give those elements unique
15
+ # IDs that don't duplicate the original element.
16
+ #
17
+ # @param id [String] the ID
18
+ #
19
+ def record_id_copied(id)
20
+ return if id.blank?
21
+
22
+ @id_data[id][:count] += 1
23
+ @id_data[id][:last_pasted] = false
24
+ end
25
+
26
+ # Keeps track that an element with the given ID has been cut.
27
+ #
28
+ # @param id [String]
29
+ #
30
+ def record_id_cut(id)
31
+ return if id.blank?
32
+
33
+ @id_data[id][:count] -= 1 if @id_data[id][:count].positive?
34
+ @id_data[id][:last_pasted] = false
35
+ end
36
+
37
+ # Keeps track that an element with the given ID has been pasted.
38
+ #
39
+ # @param id [String]
40
+ #
41
+ def record_id_pasted(id)
42
+ return if id.blank?
43
+
44
+ @id_data[id][:count] += 1 if @id_data[id][:last_pasted]
45
+ @id_data[id][:last_pasted] = true
46
+ end
47
+
48
+ # Returns a unique ID given the ID of an element that was copied and is about
49
+ # to be pasted
50
+ #
51
+ # @param original_id [String]
52
+ # @return [String]
53
+ #
54
+ def modified_id_to_paste(original_id)
55
+ return nil if original_id.nil?
56
+ return '' if original_id.blank?
57
+
58
+ count = @id_data[original_id][:count]
59
+ # A count of 0 means the element was cut and this is the first paste, do not
60
+ # modify the ID; otherwise, use the uniquified ID.
61
+ if count.zero?
62
+ original_id
63
+ else
64
+ "#{original_id}#{@id_copy_suffix}#{count}"
65
+ end
66
+ end
67
+ end
68
+ end
@@ -12,8 +12,14 @@ module Kitchen
12
12
  def initialize(node:, document: nil)
13
13
  super(node: node,
14
14
  document: document,
15
- enumerator_class: MetadataElementEnumerator,
16
- short_type: :metadata)
15
+ enumerator_class: MetadataElementEnumerator)
16
+ end
17
+
18
+ # Returns the short type
19
+ # @return [Symbol]
20
+ #
21
+ def self.short_type
22
+ :metadata
17
23
  end
18
24
 
19
25
  # Returns set of selected data elements
@@ -11,7 +11,7 @@ module Kitchen
11
11
  #
12
12
  def self.factory
13
13
  ElementEnumeratorFactory.new(
14
- default_css_or_xpath: "div[data-type='metadata']",
14
+ default_css_or_xpath: Selector.named(:metadata),
15
15
  sub_element_class: MetadataElement,
16
16
  enumerator_class: self
17
17
  )
@@ -13,8 +13,14 @@ module Kitchen
13
13
  def initialize(node:, document: nil)
14
14
  super(node: node,
15
15
  document: document,
16
- enumerator_class: NoteElementEnumerator,
17
- short_type: :note)
16
+ enumerator_class: NoteElementEnumerator)
17
+ end
18
+
19
+ # Returns the short type
20
+ # @return [Symbol]
21
+ #
22
+ def self.short_type
23
+ :note
18
24
  end
19
25
 
20
26
  # Returns the note's title element
@@ -46,15 +52,6 @@ module Kitchen
46
52
  end
47
53
  end
48
54
 
49
- # Returns true if this class represents the element for the given node
50
- #
51
- # @param node [Nokogiri::XML::Node] the underlying node
52
- # @return [Boolean]
53
- #
54
- def self.is_the_element_class_for?(node)
55
- node['data-type'] == 'note'
56
- end
57
-
58
55
  protected
59
56
 
60
57
  def detected_note_title_key
@@ -11,7 +11,7 @@ module Kitchen
11
11
  #
12
12
  def self.factory
13
13
  ElementEnumeratorFactory.new(
14
- default_css_or_xpath: "div[data-type='note']", # TODO: get from config?
14
+ default_css_or_xpath: Selector.named(:note),
15
15
  sub_element_class: NoteElement,
16
16
  enumerator_class: self
17
17
  )
data/lib/kitchen/oven.rb CHANGED
@@ -28,6 +28,8 @@ module Kitchen
28
28
  config: config
29
29
  )
30
30
 
31
+ I18n.locale = doc.locale
32
+
31
33
  [recipes].flatten.each do |recipe|
32
34
  recipe.document = doc
33
35
  recipe.bake
@@ -35,10 +37,12 @@ module Kitchen
35
37
  profile.baked!
36
38
 
37
39
  File.open(output_file, 'w') do |f|
38
- f.write doc.to_xhtml(indent: 2)
40
+ f.write doc.to_xhtml(indent: 2, encoding: doc.encoding || 'utf-8')
39
41
  end
40
42
  profile.written!
41
43
 
44
+ Nokogiri::XML.print_profile_data if ENV['PROFILE'] && !ENV['TESTING']
45
+
42
46
  profile
43
47
  end
44
48