polytypo 1.17.2 → 1.17.4

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/polytypo/data/VERSION +1 -1
  3. data/lib/polytypo/data/fixtures/bg.json +1 -1
  4. data/lib/polytypo/data/fixtures/cs.json +1 -1
  5. data/lib/polytypo/data/fixtures/de-CH.json +1 -1
  6. data/lib/polytypo/data/fixtures/de-DE.json +9 -26
  7. data/lib/polytypo/data/fixtures/el.json +1 -1
  8. data/lib/polytypo/data/fixtures/en-GB.json +225 -1
  9. data/lib/polytypo/data/fixtures/en-US.json +172 -516
  10. data/lib/polytypo/data/fixtures/es.json +1 -1
  11. data/lib/polytypo/data/fixtures/fi.json +1 -1
  12. data/lib/polytypo/data/fixtures/fr-CA.json +1 -1
  13. data/lib/polytypo/data/fixtures/fr.json +12 -37
  14. data/lib/polytypo/data/fixtures/hr.json +1 -1
  15. data/lib/polytypo/data/fixtures/hu.json +1 -1
  16. data/lib/polytypo/data/fixtures/it.json +1 -1
  17. data/lib/polytypo/data/fixtures/locale-resolution.json +1 -1
  18. data/lib/polytypo/data/fixtures/lt.json +1 -1
  19. data/lib/polytypo/data/fixtures/nl.json +1 -1
  20. data/lib/polytypo/data/fixtures/pl.json +1 -1
  21. data/lib/polytypo/data/fixtures/pt-BR.json +1 -1
  22. data/lib/polytypo/data/fixtures/pt-PT.json +1 -1
  23. data/lib/polytypo/data/fixtures/ro.json +1 -1
  24. data/lib/polytypo/data/fixtures/ru.json +1 -1
  25. data/lib/polytypo/data/fixtures/sk.json +1 -1
  26. data/lib/polytypo/data/fixtures/sl.json +1 -1
  27. data/lib/polytypo/data/fixtures/sr.json +1 -1
  28. data/lib/polytypo/data/fixtures/sv.json +1 -1
  29. data/lib/polytypo/data/fixtures/tr.json +1 -1
  30. data/lib/polytypo/data/fixtures/uk.json +1 -1
  31. data/lib/polytypo/data/locales/registry.json +1 -1
  32. data/lib/polytypo/data/rules/modes.md +71 -6
  33. data/lib/polytypo/data/rules/order.json +1 -1
  34. data/lib/polytypo/modes/html.rb +0 -1
  35. data/lib/polytypo/modes/markdown.rb +67 -12
  36. data/lib/polytypo/modes/runner.rb +2 -3
  37. data/lib/polytypo/modes/spans.rb +59 -5
  38. data/lib/polytypo/version.rb +1 -1
  39. metadata +1 -1
@@ -138,6 +138,57 @@ module Polytypo
138
138
  end
139
139
  private_class_method :changes_delimiter_flank?
140
140
 
141
+ def self.ascii_punctuation?(c)
142
+ return false if c.nil?
143
+
144
+ (c >= 0x21 && c <= 0x2F) || (c >= 0x3A && c <= 0x40) || (c >= 0x5B && c <= 0x60) ||
145
+ (c >= 0x7B && c <= 0x7E)
146
+ end
147
+ private_class_method :ascii_punctuation?
148
+
149
+ def self.ascii_alphanumeric?(c)
150
+ return false if c.nil?
151
+
152
+ (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A)
153
+ end
154
+ private_class_method :ascii_alphanumeric?
155
+
156
+ # modes.md 3.4 escape-and-reference rule, item 1 (markdown only, spec 1.17.4): an edit is
157
+ # discarded when it follows a backslash and changes whether the first code point after the
158
+ # backslash is ASCII punctuation, which would create or destroy a backslash escape.
159
+ def self.creates_escape?(cp, p, q, replacement)
160
+ return false if (p - 1).negative? || cp[p - 1] != 0x5C
161
+
162
+ after = replacement.empty? ? cp[q + 1] : replacement[0]
163
+ ascii_punctuation?(cp[p]) != ascii_punctuation?(after)
164
+ end
165
+ private_class_method :creates_escape?
166
+
167
+ # modes.md 3.4 escape-and-reference rule, item 2 (markdown and html, spec 1.17.4): a deletion
168
+ # that makes "&", an optional "#", one or more ASCII letters or digits and ";" adjacent
169
+ # around the join. A marker is in no class and stops either scan.
170
+ def self.creates_reference?(cp, p, q, replacement)
171
+ return false if !replacement.empty? || (p - 1).negative? || q + 1 >= cp.length
172
+
173
+ left = p - 1
174
+ alnum = 0
175
+ while left >= 0 && ascii_alphanumeric?(cp[left])
176
+ left -= 1
177
+ alnum += 1
178
+ end
179
+ right = q + 1
180
+ right += 1 if left >= 0 && cp[left] == 0x26 && cp[right] == 0x23 && alnum.zero?
181
+ while right < cp.length && ascii_alphanumeric?(cp[right])
182
+ right += 1
183
+ alnum += 1
184
+ end
185
+ return false if cp[right] != 0x3B || alnum.zero?
186
+
187
+ left -= 1 if left >= 0 && cp[left] == 0x23
188
+ left >= 0 && cp[left] == 0x26
189
+ end
190
+ private_class_method :creates_reference?
191
+
141
192
  # modes.md 3.4, two safety nets, both pure functions of (p, q, r, s0, s1):
142
193
  #
143
194
  # 1. No edit may contain a marker -- one that does is a bug, discarded rather than
@@ -151,10 +202,10 @@ module Polytypo
151
202
  # point any rule emits whose meaning comes from its position rather than from itself
152
203
  # (modes.md 5 item 2).
153
204
  #
154
- # +delimiter_neighbours+ (markdown only) enables the delimiter-neighbour rule of modes.md 3.4,
155
- # and +guarded+ holds, per span, whether its first code point is the terminator of a bare web
156
- # address (modes.md 3.7.3); both spec 1.17.2.
157
- def self.filter_boundary_edits(cp, edits, ranges, delimiter_neighbours: false, guarded: [])
205
+ # +mode+ selects the neighbour rules of modes.md 3.4 -- delimiter-neighbour and the escape rule
206
+ # for markdown, the reference rule for markdown and html -- and +guarded+ holds, per span,
207
+ # whether its first code point is the terminator of a bare web address (modes.md 3.7.3).
208
+ def self.filter_boundary_edits(cp, edits, ranges, mode: nil, guarded: [])
158
209
  edits.select do |edit|
159
210
  next false if (edit.start...edit.end).any? { |i| Engine.marker?(cp[i]) }
160
211
 
@@ -162,7 +213,10 @@ module Polytypo
162
213
  q = edit.end - 1
163
214
  d = edit.end - edit.start
164
215
  r = edit.replacement.length
165
- next false if delimiter_neighbours && changes_delimiter_flank?(cp, p, q, edit.replacement)
216
+ markdown = mode == "markdown"
217
+ next false if markdown && changes_delimiter_flank?(cp, p, q, edit.replacement)
218
+ next false if markdown && creates_escape?(cp, p, q, edit.replacement)
219
+ next false if (markdown || mode == "html") && creates_reference?(cp, p, q, edit.replacement)
166
220
 
167
221
  span = span_containing(ranges, p)
168
222
  if span && p == span.first && guarded[ranges.index(span)] == true &&
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polytypo
4
- VERSION = "1.17.2"
4
+ VERSION = "1.17.4"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polytypo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.2
4
+ version: 1.17.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iurii Rogulia