canon 0.3.62 → 0.3.63

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5ab88d04204cba8fb555ca3ebae0091a6a9d22fbb5e06e58974195e6bace30d
4
- data.tar.gz: 3f952b1cb790351630ba1cb659e69492e67ff34ede453c98624877df4bb9b5f5
3
+ metadata.gz: 0a25343915041867345d470570eb9a84d2266e4b95b89b730bee32a0a99b112f
4
+ data.tar.gz: 501f8c0e6c7430611a0c68c3b31b2d30ce63ec411bd6426e854fdb9c57a4f6ac
5
5
  SHA512:
6
- metadata.gz: 6128ca89822cbf059a28e3f753d42a56e3ab40fd5ed98bb4cca9a467ae1124387b443747d0d480eb0da1bfd8358bc17e870dc4709e12c857b427bd35c56479c4
7
- data.tar.gz: 1f6100fa01d92715eac814bb0538172b7ebc993cddbeaea34855631a76880cbf5b791403ba581c9b446a7903784aa1217542bc7c45ea18174b3e27eec2d7fb1d
6
+ metadata.gz: df2fb54642dffbc16670860f406bfce3e76d4665772d5d0394dd65762157ce821ab8d315c8a761abfd3d6ac9a72467039549fccaedfc5ea0ac7596852a898e28
7
+ data.tar.gz: 31781f1ef8b498980a1ca4036ebf9337f6716744f9f6d6e11519aa5ca4d0356d18c6679bc9091a10280b466abab0471e199c9db0d5c4138a27e992dff2af5623
@@ -17,8 +17,60 @@ module Canon
17
17
  # If only one is blank, it's not just formatting
18
18
  return false if blank?(line1) || blank?(line2)
19
19
 
20
- # Compare normalized versions
21
- normalize_for_comparison(line1) == normalize_for_comparison(line2)
20
+ return true if line1 == line2
21
+
22
+ # Identical prefix/suffix bytes normalize identically — compare
23
+ # only the differing core, widened to tag boundaries so no tag,
24
+ # entity, or whitespace run spans a cut (the normalization is
25
+ # then compositional across the cut points).
26
+ core1, core2 = differing_core(line1, line2)
27
+ return false if core1.nil?
28
+
29
+ normalize_for_comparison(core1) == normalize_for_comparison(core2)
30
+ end
31
+
32
+ # The differing core of two lines: the region between the common
33
+ # prefix and common suffix, widened outward to just after a ">" so
34
+ # the cuts never split a tag, an entity reference, or a whitespace
35
+ # run. Returns nil when the bytes are identical (no core).
36
+ #
37
+ # @param line1 [String]
38
+ # @param line2 [String]
39
+ # @return [Array(String, String), nil]
40
+ def self.differing_core(line1, line2)
41
+ return nil if line1 == line2
42
+
43
+ size1 = line1.bytesize
44
+ size2 = line2.bytesize
45
+ limit = [size1, size2].min
46
+ lo = 0
47
+ lo += 1 while lo < limit && line1.getbyte(lo) == line2.getbyte(lo)
48
+
49
+ suffix_max = limit - lo
50
+ s = 0
51
+ s += 1 while s < suffix_max &&
52
+ line1.getbyte(size1 - 1 - s) == line2.getbyte(size2 - 1 - s)
53
+
54
+ # Snap the cuts to tag boundaries (the shared regions are
55
+ # identical, so the cuts apply to both lines alike): the left
56
+ # cut moves to the start of the enclosing tag so attribute
57
+ # normalization always sees whole tags; the right cut moves
58
+ # past the closing ">".
59
+ tag_lo = line1.rindex("<", lo)
60
+ lo = tag_lo if tag_lo
61
+
62
+ hi1 = size1 - s
63
+ hi2 = size2 - s
64
+ tag_hi = line1.index(">", hi1)
65
+ if tag_hi
66
+ hi1 = tag_hi + 1
67
+ hi2 = hi1 + (size2 - size1) # same offset within the shared tail
68
+ end
69
+
70
+ # Degenerate widening (empty core) — compare the full lines.
71
+ return [line1, line2] if lo > hi1 || hi2 < lo
72
+
73
+ [line1[lo...hi1], line2[lo...hi2]]
22
74
  end
23
75
 
24
76
  # Aggressive normalization for formatting comparison.
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.3.62"
4
+ VERSION = "0.3.63"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.62
4
+ version: 0.3.63
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.