diff-lcs 1.3 → 1.6.2

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.
Files changed (118) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +518 -0
  3. data/CODE_OF_CONDUCT.md +128 -0
  4. data/CONTRIBUTING.md +71 -0
  5. data/CONTRIBUTORS.md +49 -0
  6. data/{License.md → LICENCE.md} +21 -20
  7. data/Manifest.txt +84 -6
  8. data/README.md +92 -0
  9. data/Rakefile +104 -46
  10. data/SECURITY.md +41 -0
  11. data/bin/htmldiff +9 -6
  12. data/bin/ldiff +4 -1
  13. data/docs/artistic.txt +1 -1
  14. data/lib/diff/lcs/array.rb +2 -2
  15. data/lib/diff/lcs/backports.rb +13 -0
  16. data/lib/diff/lcs/block.rb +5 -5
  17. data/lib/diff/lcs/callbacks.rb +22 -17
  18. data/lib/diff/lcs/change.rb +44 -51
  19. data/lib/diff/lcs/htmldiff.rb +25 -14
  20. data/lib/diff/lcs/hunk.rb +174 -71
  21. data/lib/diff/lcs/internals.rb +57 -56
  22. data/lib/diff/lcs/ldiff.rb +101 -79
  23. data/lib/diff/lcs/string.rb +1 -1
  24. data/lib/diff/lcs/version.rb +7 -0
  25. data/lib/diff/lcs.rb +229 -212
  26. data/lib/diff-lcs.rb +2 -2
  27. data/mise.toml +5 -0
  28. data/spec/change_spec.rb +58 -34
  29. data/spec/diff_spec.rb +13 -9
  30. data/spec/fixtures/123_x +2 -0
  31. data/spec/fixtures/456_x +2 -0
  32. data/spec/fixtures/aX +1 -0
  33. data/spec/fixtures/bXaX +1 -0
  34. data/spec/fixtures/empty +0 -0
  35. data/spec/fixtures/file1.bin +0 -0
  36. data/spec/fixtures/file2.bin +0 -0
  37. data/spec/fixtures/four_lines +4 -0
  38. data/spec/fixtures/four_lines_with_missing_new_line +4 -0
  39. data/spec/fixtures/ldiff/diff.missing_new_line1-e +1 -0
  40. data/spec/fixtures/ldiff/diff.missing_new_line1-f +1 -0
  41. data/spec/fixtures/ldiff/diff.missing_new_line2-e +1 -0
  42. data/spec/fixtures/ldiff/diff.missing_new_line2-f +1 -0
  43. data/spec/fixtures/ldiff/error.diff.chef-e +2 -0
  44. data/spec/fixtures/ldiff/error.diff.chef-f +2 -0
  45. data/spec/fixtures/ldiff/error.diff.missing_new_line1-e +1 -0
  46. data/spec/fixtures/ldiff/error.diff.missing_new_line1-f +1 -0
  47. data/spec/fixtures/ldiff/error.diff.missing_new_line2-e +1 -0
  48. data/spec/fixtures/ldiff/error.diff.missing_new_line2-f +1 -0
  49. data/spec/fixtures/ldiff/output.diff +4 -0
  50. data/spec/fixtures/ldiff/output.diff-c +7 -0
  51. data/spec/fixtures/ldiff/output.diff-e +3 -0
  52. data/spec/fixtures/ldiff/output.diff-f +3 -0
  53. data/spec/fixtures/ldiff/output.diff-u +5 -0
  54. data/spec/fixtures/ldiff/output.diff.bin1 +0 -0
  55. data/spec/fixtures/ldiff/output.diff.bin1-c +0 -0
  56. data/spec/fixtures/ldiff/output.diff.bin1-e +0 -0
  57. data/spec/fixtures/ldiff/output.diff.bin1-f +0 -0
  58. data/spec/fixtures/ldiff/output.diff.bin1-u +0 -0
  59. data/spec/fixtures/ldiff/output.diff.bin2 +1 -0
  60. data/spec/fixtures/ldiff/output.diff.bin2-c +1 -0
  61. data/spec/fixtures/ldiff/output.diff.bin2-e +1 -0
  62. data/spec/fixtures/ldiff/output.diff.bin2-f +1 -0
  63. data/spec/fixtures/ldiff/output.diff.bin2-u +1 -0
  64. data/spec/fixtures/ldiff/output.diff.chef +4 -0
  65. data/spec/fixtures/ldiff/output.diff.chef-c +15 -0
  66. data/spec/fixtures/ldiff/output.diff.chef-e +3 -0
  67. data/spec/fixtures/ldiff/output.diff.chef-f +3 -0
  68. data/spec/fixtures/ldiff/output.diff.chef-u +9 -0
  69. data/spec/fixtures/ldiff/output.diff.chef2 +7 -0
  70. data/spec/fixtures/ldiff/output.diff.chef2-c +20 -0
  71. data/spec/fixtures/ldiff/output.diff.chef2-d +7 -0
  72. data/spec/fixtures/ldiff/output.diff.chef2-e +7 -0
  73. data/spec/fixtures/ldiff/output.diff.chef2-f +7 -0
  74. data/spec/fixtures/ldiff/output.diff.chef2-u +16 -0
  75. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines +5 -0
  76. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +9 -0
  77. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e +6 -0
  78. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f +6 -0
  79. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +7 -0
  80. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty +5 -0
  81. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +9 -0
  82. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e +1 -0
  83. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f +1 -0
  84. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +7 -0
  85. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context +4 -0
  86. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +9 -0
  87. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e +3 -0
  88. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f +3 -0
  89. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +6 -0
  90. data/spec/fixtures/ldiff/output.diff.missing_new_line1 +5 -0
  91. data/spec/fixtures/ldiff/output.diff.missing_new_line1-c +14 -0
  92. data/spec/fixtures/ldiff/output.diff.missing_new_line1-e +0 -0
  93. data/spec/fixtures/ldiff/output.diff.missing_new_line1-f +0 -0
  94. data/spec/fixtures/ldiff/output.diff.missing_new_line1-u +9 -0
  95. data/spec/fixtures/ldiff/output.diff.missing_new_line2 +5 -0
  96. data/spec/fixtures/ldiff/output.diff.missing_new_line2-c +14 -0
  97. data/spec/fixtures/ldiff/output.diff.missing_new_line2-e +0 -0
  98. data/spec/fixtures/ldiff/output.diff.missing_new_line2-f +0 -0
  99. data/spec/fixtures/ldiff/output.diff.missing_new_line2-u +9 -0
  100. data/spec/fixtures/new-chef +4 -0
  101. data/spec/fixtures/new-chef2 +17 -0
  102. data/spec/fixtures/old-chef +4 -0
  103. data/spec/fixtures/old-chef2 +14 -0
  104. data/spec/hunk_spec.rb +49 -38
  105. data/spec/issues_spec.rb +132 -21
  106. data/spec/lcs_spec.rb +3 -3
  107. data/spec/ldiff_spec.rb +83 -30
  108. data/spec/patch_spec.rb +14 -20
  109. data/spec/sdiff_spec.rb +83 -81
  110. data/spec/spec_helper.rb +220 -165
  111. data/spec/traverse_balanced_spec.rb +138 -136
  112. data/spec/traverse_sequences_spec.rb +7 -9
  113. metadata +127 -77
  114. data/Code-of-Conduct.md +0 -74
  115. data/Contributing.md +0 -83
  116. data/History.md +0 -220
  117. data/README.rdoc +0 -84
  118. data/autotest/discover.rb +0 -1
@@ -1,4 +1,4 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  # A block is an operation removing, adding, or changing a group of items.
4
4
  # Basically, this is just a list of changes, where each change adds or
@@ -25,13 +25,13 @@ class Diff::LCS::Block
25
25
  def op
26
26
  case [@remove.empty?, @insert.empty?]
27
27
  when [false, false]
28
- '!'
28
+ "!"
29
29
  when [false, true]
30
- '-'
30
+ "-"
31
31
  when [true, false]
32
- '+'
32
+ "+"
33
33
  else # [true, true]
34
- '^'
34
+ "^"
35
35
  end
36
36
  end
37
37
  end
@@ -1,6 +1,6 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- require 'diff/lcs/change'
3
+ require "diff/lcs/change"
4
4
 
5
5
  module Diff::LCS
6
6
  # This callback object implements the default set of callback events,
@@ -17,14 +17,17 @@ module Diff::LCS
17
17
  def match(event)
18
18
  event
19
19
  end
20
+
20
21
  # Called when the old value is discarded in favour of the new value.
21
22
  def discard_a(event)
22
23
  event
23
24
  end
25
+
24
26
  # Called when the new value is discarded in favour of the old value.
25
27
  def discard_b(event)
26
28
  event
27
29
  end
30
+
28
31
  # Called when both the old and new values have changed.
29
32
  def change(event)
30
33
  event
@@ -47,7 +50,9 @@ module Diff::LCS
47
50
  BalancedCallbacks = DefaultCallbacks
48
51
 
49
52
  def self.callbacks_for(callbacks)
50
- callbacks.new rescue callbacks
53
+ callbacks.new
54
+ rescue
55
+ callbacks
51
56
  end
52
57
  end
53
58
 
@@ -104,16 +109,16 @@ class Diff::LCS::DiffCallbacks
104
109
  # Returns the difference set collected during the diff process.
105
110
  attr_reader :diffs
106
111
 
107
- def initialize # :yields self:
112
+ def initialize # :yields: self
108
113
  @hunk = []
109
114
  @diffs = []
110
115
 
111
- if block_given?
112
- begin
113
- yield self
114
- ensure
115
- self.finish
116
- end
116
+ return unless block_given?
117
+
118
+ begin
119
+ yield self
120
+ ensure
121
+ finish
117
122
  end
118
123
  end
119
124
 
@@ -123,16 +128,16 @@ class Diff::LCS::DiffCallbacks
123
128
  finish_hunk
124
129
  end
125
130
 
126
- def match(event)
131
+ def match(_event)
127
132
  finish_hunk
128
133
  end
129
134
 
130
135
  def discard_a(event)
131
- @hunk << Diff::LCS::Change.new('-', event.old_position, event.old_element)
136
+ @hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element)
132
137
  end
133
138
 
134
139
  def discard_b(event)
135
- @hunk << Diff::LCS::Change.new('+', event.new_position, event.new_element)
140
+ @hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element)
136
141
  end
137
142
 
138
143
  def finish_hunk
@@ -190,7 +195,7 @@ end
190
195
  # Diff::LCS::SDiffCallbacks. They may be compared as:
191
196
  #
192
197
  # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
193
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
198
+ # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1)
194
199
  #
195
200
  # s == c # -> true
196
201
  #
@@ -241,7 +246,7 @@ end
241
246
  # will compute and display the necessary components to show two sequences
242
247
  # and their minimized differences side by side, just like the Unix utility
243
248
  # +sdiff+.
244
- #
249
+ #
245
250
  # same same
246
251
  # before | after
247
252
  # old < -
@@ -270,7 +275,7 @@ end
270
275
  # Diff::LCS::ContextDiffCallbacks. They may be compared as:
271
276
  #
272
277
  # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
273
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
278
+ # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1)
274
279
  #
275
280
  # s == c # -> true
276
281
  #
@@ -299,7 +304,7 @@ class Diff::LCS::SDiffCallbacks
299
304
  # Returns the difference set collected during the diff process.
300
305
  attr_reader :diffs
301
306
 
302
- def initialize #:yields self:
307
+ def initialize # :yields: self
303
308
  @diffs = []
304
309
  yield self if block_given?
305
310
  end
@@ -1,16 +1,16 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  # Represents a simplistic (non-contextual) change. Represents the removal or
4
4
  # addition of an element from either the old or the new sequenced
5
5
  # enumerable.
6
6
  class Diff::LCS::Change
7
- IntClass = 1.class # Fixnum is deprecated in Ruby 2.4
7
+ IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName
8
8
 
9
9
  # The only actions valid for changes are '+' (add), '-' (delete), '='
10
10
  # (no change), '!' (changed), '<' (tail changes from first sequence), or
11
11
  # '>' (tail changes from second sequence). The last two ('<>') are only
12
12
  # found with Diff::LCS::diff and Diff::LCS::sdiff.
13
- VALID_ACTIONS = %W(+ - = ! > <)
13
+ VALID_ACTIONS = %w[+ - = ! > <].freeze
14
14
 
15
15
  def self.valid_action?(action)
16
16
  VALID_ACTIONS.include? action
@@ -27,29 +27,29 @@ class Diff::LCS::Change
27
27
  def initialize(*args)
28
28
  @action, @position, @element = *args
29
29
 
30
- unless Diff::LCS::Change.valid_action?(@action)
31
- raise "Invalid Change Action '#{@action}'"
32
- end
33
- raise "Invalid Position Type" unless @position.kind_of? IntClass
30
+ fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
31
+ fail "Invalid Position Type" unless @position.is_a? IntClass
34
32
  end
35
33
 
36
- def inspect
37
- to_a.inspect
34
+ def inspect(*_args)
35
+ "#<#{self.class}: #{to_a.inspect}>"
38
36
  end
39
37
 
40
38
  def to_a
41
- [ @action, @position, @element ]
39
+ [@action, @position, @element]
42
40
  end
43
41
 
42
+ alias_method :to_ary, :to_a
43
+
44
44
  def self.from_a(arr)
45
45
  arr = arr.flatten(1)
46
46
  case arr.size
47
47
  when 5
48
- Diff::LCS::ContextChange.new(*(arr[0...5]))
48
+ Diff::LCS::ContextChange.new(*arr[0...5])
49
49
  when 3
50
- Diff::LCS::Change.new(*(arr[0...3]))
50
+ Diff::LCS::Change.new(*arr[0...3])
51
51
  else
52
- raise "Invalid change array format provided."
52
+ fail "Invalid change array format provided."
53
53
  end
54
54
  end
55
55
 
@@ -57,40 +57,40 @@ class Diff::LCS::Change
57
57
 
58
58
  def ==(other)
59
59
  (self.class == other.class) and
60
- (self.action == other.action) and
61
- (self.position == other.position) and
62
- (self.element == other.element)
60
+ (action == other.action) and
61
+ (position == other.position) and
62
+ (element == other.element)
63
63
  end
64
64
 
65
65
  def <=>(other)
66
- r = self.action <=> other.action
67
- r = self.position <=> other.position if r.zero?
68
- r = self.element <=> other.element if r.zero?
66
+ r = action <=> other.action
67
+ r = position <=> other.position if r.zero?
68
+ r = element <=> other.element if r.zero?
69
69
  r
70
70
  end
71
71
 
72
72
  def adding?
73
- @action == '+'
73
+ @action == "+"
74
74
  end
75
75
 
76
76
  def deleting?
77
- @action == '-'
77
+ @action == "-"
78
78
  end
79
79
 
80
80
  def unchanged?
81
- @action == '='
81
+ @action == "="
82
82
  end
83
83
 
84
84
  def changed?
85
- @action == '!'
85
+ @action == "!"
86
86
  end
87
87
 
88
88
  def finished_a?
89
- @action == '>'
89
+ @action == ">"
90
90
  end
91
91
 
92
92
  def finished_b?
93
- @action == '<'
93
+ @action == "<"
94
94
  end
95
95
  end
96
96
 
@@ -114,27 +114,20 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
114
114
  def initialize(*args)
115
115
  @action, @old_position, @old_element, @new_position, @new_element = *args
116
116
 
117
- unless Diff::LCS::Change.valid_action?(@action)
118
- raise "Invalid Change Action '#{@action}'"
119
- end
120
- unless @old_position.nil? or @old_position.kind_of? IntClass
121
- raise "Invalid (Old) Position Type"
122
- end
123
- unless @new_position.nil? or @new_position.kind_of? IntClass
124
- raise "Invalid (New) Position Type"
125
- end
117
+ fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
118
+ fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass)
119
+ fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass)
126
120
  end
127
121
 
128
122
  def to_a
129
- [ @action,
130
- [ @old_position, @old_element ],
131
- [ @new_position, @new_element ]
123
+ [
124
+ @action,
125
+ [@old_position, @old_element],
126
+ [@new_position, @new_element]
132
127
  ]
133
128
  end
134
129
 
135
- def inspect(*args)
136
- to_a.inspect
137
- end
130
+ alias_method :to_ary, :to_a
138
131
 
139
132
  def self.from_a(arr)
140
133
  Diff::LCS::Change.from_a(arr)
@@ -146,15 +139,15 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
146
139
  ea = event.to_a
147
140
 
148
141
  case ea[0]
149
- when '-'
142
+ when "-"
150
143
  ea[2][1] = nil
151
- when '<'
152
- ea[0] = '-'
144
+ when "<"
145
+ ea[0] = "-"
153
146
  ea[2][1] = nil
154
- when '+'
147
+ when "+"
155
148
  ea[1][1] = nil
156
- when '>'
157
- ea[0] = '+'
149
+ when ">"
150
+ ea[0] = "+"
158
151
  ea[1][1] = nil
159
152
  end
160
153
 
@@ -163,11 +156,11 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
163
156
 
164
157
  def ==(other)
165
158
  (self.class == other.class) and
166
- (@action == other.action) and
167
- (@old_position == other.old_position) and
168
- (@new_position == other.new_position) and
169
- (@old_element == other.old_element) and
170
- (@new_element == other.new_element)
159
+ (@action == other.action) and
160
+ (@old_position == other.old_position) and
161
+ (@new_position == other.new_position) and
162
+ (@old_element == other.old_element) and
163
+ (@new_element == other.new_element)
171
164
  end
172
165
 
173
166
  def <=>(other)
@@ -1,14 +1,17 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- require 'cgi'
3
+ require "erb"
4
4
 
5
+ # Produce a simple HTML diff view.
5
6
  class Diff::LCS::HTMLDiff
6
7
  class << self
7
- attr_accessor :can_expand_tabs #:nodoc:
8
+ # standard:disable ThreadSafety/ClassAndModuleAttributes
9
+ attr_accessor :can_expand_tabs # :nodoc:
10
+ # standard:enable ThreadSafety/ClassAndModuleAttributes
8
11
  end
9
12
  self.can_expand_tabs = true
10
13
 
11
- class Callbacks
14
+ class Callbacks # :nodoc:
12
15
  attr_accessor :output
13
16
  attr_accessor :match_class
14
17
  attr_accessor :only_a_class
@@ -25,7 +28,7 @@ class Diff::LCS::HTMLDiff
25
28
 
26
29
  def htmlize(element, css_class)
27
30
  element = "&nbsp;" if element.empty?
28
- %Q|<pre class="#{__send__(css_class)}">#{element}</pre>\n|
31
+ %(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
29
32
  end
30
33
  private :htmlize
31
34
 
@@ -45,13 +48,16 @@ class Diff::LCS::HTMLDiff
45
48
  end
46
49
  end
47
50
 
51
+ # standard:disable Style/HashSyntax
48
52
  DEFAULT_OPTIONS = {
49
53
  :expand_tabs => nil,
50
54
  :output => nil,
51
55
  :css => nil,
52
- :title => nil,
53
- }
56
+ :title => nil
57
+ }.freeze
58
+ # standard:enable Style/HashSyntax
54
59
 
60
+ # standard:disable Layout/HeredocIndentation
55
61
  DEFAULT_CSS = <<-CSS
56
62
  body { margin: 0; }
57
63
  .diff
@@ -85,18 +91,19 @@ pre
85
91
  }
86
92
  h1 { margin-left: 2em; }
87
93
  CSS
94
+ # standard:enable Layout/HeredocIndentation
88
95
 
89
96
  def initialize(left, right, options = nil)
90
- @left = left
91
- @right = right
92
- @options = options
97
+ @left = left
98
+ @right = right
99
+ @options = options
93
100
 
94
101
  @options = DEFAULT_OPTIONS.dup if @options.nil?
95
102
  end
96
103
 
97
104
  def verify_options
98
105
  @options[:expand_tabs] ||= 4
99
- @options[:expand_tabs] = 4 if @options[:expand_tabs] < 0
106
+ @options[:expand_tabs] = 4 if @options[:expand_tabs].negative?
100
107
 
101
108
  @options[:output] ||= $stdout
102
109
 
@@ -111,7 +118,7 @@ h1 { margin-left: 2em; }
111
118
  def run
112
119
  verify_options
113
120
 
114
- if @options[:expand_tabs] > 0 && self.class.can_expand_tabs
121
+ if @options[:expand_tabs].positive? && self.class.can_expand_tabs
115
122
  formatter = Text::Format.new
116
123
  formatter.tabstop = @options[:expand_tabs]
117
124
 
@@ -119,9 +126,10 @@ h1 { margin-left: 2em; }
119
126
  @right.map! { |line| formatter.expand(line.chomp) }
120
127
  end
121
128
 
122
- @left.map! { |line| CGI.escapeHTML(line.chomp) }
123
- @right.map! { |line| CGI.escapeHTML(line.chomp) }
129
+ @left.map! { |line| ERB::Util.html_escape(line.chomp) }
130
+ @right.map! { |line| ERB::Util.html_escape(line.chomp) }
124
131
 
132
+ # standard:disable Layout/HeredocIndentation
125
133
  @options[:output] << <<-OUTPUT
126
134
  <html>
127
135
  <head>
@@ -136,14 +144,17 @@ h1 { margin-left: 2em; }
136
144
  <span class="only_b">Only in New</span></p>
137
145
  <div class="diff">
138
146
  OUTPUT
147
+ # standard:enable Layout/HeredocIndentation
139
148
 
140
149
  callbacks = Callbacks.new(@options[:output])
141
150
  Diff::LCS.traverse_sequences(@left, @right, callbacks)
142
151
 
152
+ # standard:disable Layout/HeredocIndentation
143
153
  @options[:output] << <<-OUTPUT
144
154
  </div>
145
155
  </body>
146
156
  </html>
147
157
  OUTPUT
158
+ # standard:enable Layout/HeredocIndentation
148
159
  end
149
160
  end