polytypo 1.12.0 → 1.14.0

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -1
  3. data/lib/polytypo/data/VERSION +1 -1
  4. data/lib/polytypo/data/fixtures/bg.json +1 -1
  5. data/lib/polytypo/data/fixtures/cs.json +1 -1
  6. data/lib/polytypo/data/fixtures/de-CH.json +1 -1
  7. data/lib/polytypo/data/fixtures/de-DE.json +77 -1
  8. data/lib/polytypo/data/fixtures/el.json +1 -1
  9. data/lib/polytypo/data/fixtures/en-GB.json +89 -1
  10. data/lib/polytypo/data/fixtures/en-US.json +450 -1
  11. data/lib/polytypo/data/fixtures/es.json +1 -1
  12. data/lib/polytypo/data/fixtures/fi.json +1 -1
  13. data/lib/polytypo/data/fixtures/fr-CA.json +1 -1
  14. data/lib/polytypo/data/fixtures/fr.json +41 -1
  15. data/lib/polytypo/data/fixtures/hr.json +1 -1
  16. data/lib/polytypo/data/fixtures/hu.json +1 -1
  17. data/lib/polytypo/data/fixtures/it.json +1 -1
  18. data/lib/polytypo/data/fixtures/locale-resolution.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/sr.json +183 -0
  27. data/lib/polytypo/data/fixtures/sv.json +1 -1
  28. data/lib/polytypo/data/fixtures/tr.json +1 -1
  29. data/lib/polytypo/data/fixtures/uk.json +1 -1
  30. data/lib/polytypo/data/locales/registry.json +3 -2
  31. data/lib/polytypo/data/locales/sr.json +82 -0
  32. data/lib/polytypo/data/rules/analyze.md +16 -4
  33. data/lib/polytypo/data/rules/modes.md +262 -9
  34. data/lib/polytypo/data/rules/order.json +1 -1
  35. data/lib/polytypo/data/schema/fixtures.schema.json +160 -18
  36. data/lib/polytypo/engine/origin.rb +13 -1
  37. data/lib/polytypo/engine/protect.rb +122 -0
  38. data/lib/polytypo/errors.rb +1 -1
  39. data/lib/polytypo/modes/runner.rb +0 -1
  40. data/lib/polytypo/version.rb +1 -1
  41. data/lib/polytypo.rb +34 -19
  42. metadata +4 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c8aba5b27eb6b2b852217b3c4ba1652d78fee2fd291ce2a14e8cfc36da9ea5f
4
- data.tar.gz: 321cf32a34decf2b526b6ae4231df91cf8a7d07c96b55a211b25582e701c9abe
3
+ metadata.gz: 40f4b8a41c44a06a195e83cbc9d8928d82b6ae5ae314c22e263063451fee27d8
4
+ data.tar.gz: f1a9c674f4bb0fac75872802b3ede5c10063a85cb4c80919a737aa6f49a2c640
5
5
  SHA512:
6
- metadata.gz: d4ba1cd320aeaca4076180463c47d0d802fa3c0c9672a34326bbef2cd39ce6308b1209454792eccc2a534aec8476c840413b9f4cdddbd8cf248ef0f7205c1f0f
7
- data.tar.gz: f5dd45b49cec16dcfdca6994646d6083242cfc8cb1357ec687786bfb73f24390af6b940fe49570ab0183d6507c79c4bb29581c5fdd40caa208a4bc2d3666845d
6
+ metadata.gz: d29173f633da9a14abffef5db46f2052fdd5928429b35192865cf677aa3503d0e8b836f2eb9d66dea9a8a4d8b315008ff2367673d3992e98c6e87c012f26a8e5
7
+ data.tar.gz: 37aeef545d793fb1a99659c7fc1d2f9ebfce3c24800a16060d3d3f4597dccd8b091fe3d2097ca2008bd9a0675730fe380f5d5732ed61f6a904ab1e91645c7baa
data/README.md CHANGED
@@ -110,6 +110,26 @@ the `''` is left alone and the text on either side is processed. The block is al
110
110
  the body, which shows up in exactly one place: an unbalanced quotation mark in `title` cannot pair
111
111
  with a mark in your first paragraph.
112
112
 
113
+ ### Protecting regions of a text
114
+
115
+ In `text` mode, `protect:` names ranges of the input that are never edited and that the rules read
116
+ as opaque content, which is what a template hole is: `${…}` in a JavaScript template literal, an
117
+ ICU argument, a `{{ … }}` tag. Ranges are `[start, end]` pairs of code-point offsets (not bytes and
118
+ not UTF-16 units), half-open, ascending and non-overlapping; touching ranges are one run.
119
+
120
+ ```ruby
121
+ Polytypo.transform("${x} - Rules", locale: "en-US", protect: [[0, 4]])
122
+ # => "${x}—Rules"
123
+ Polytypo.transform("${x} - Rules", locale: "en-GB", protect: [[0, 4]])
124
+ # => "${x} – Rules"
125
+ ```
126
+
127
+ The protected code points come back exactly as written. Edits before a range shift it, so a second
128
+ call over the output needs the ranges at their new offsets; `transform` does not return them.
129
+ `nil` and `[]` mean no protection. A malformed range, or a non-empty list in `html`, `markdown` or
130
+ `yaml` mode, raises `Polytypo::Error` with `POLYTYPO_INVALID_OPTION`. `Polytypo.analyze` takes the
131
+ same option and reports offsets into the input as passed.
132
+
113
133
  `require "polytypo"` never loads the native `commonmarker` extension unless you actually call
114
134
  `Polytypo.transform` with `mode: "markdown"` — the require happens lazily, inside the markdown
115
135
  pipeline only. A single `Polytypo.transform` module method (not separate
@@ -135,7 +155,7 @@ no-break one back), so replaying the list is not guaranteed to reproduce the out
135
155
 
136
156
  ### Errors
137
157
 
138
- Every error `Polytypo.transform` raises is a `Polytypo::Error` carrying one of seven stable
158
+ Every error `Polytypo.transform` raises is a `Polytypo::Error` carrying one of eight stable
139
159
  codes — check `#code`, not the message text, which is English and informative but not part of
140
160
  the contract:
141
161
 
@@ -1 +1 @@
1
- 1.12.0
1
+ 1.14.0
@@ -1,5 +1,5 @@
1
1
  {
2
- "spec": "1.12.0",
2
+ "spec": "1.14.0",
3
3
  "locale": "bg",
4
4
  "cases": [
5
5
  {
@@ -1,5 +1,5 @@
1
1
  {
2
- "spec": "1.12.0",
2
+ "spec": "1.14.0",
3
3
  "locale": "cs",
4
4
  "cases": [
5
5
  {
@@ -1,5 +1,5 @@
1
1
  {
2
- "spec": "1.12.0",
2
+ "spec": "1.14.0",
3
3
  "locale": "de-CH",
4
4
  "cases": [
5
5
  {
@@ -1,5 +1,5 @@
1
1
  {
2
- "spec": "1.12.0",
2
+ "spec": "1.14.0",
3
3
  "locale": "de-DE",
4
4
  "cases": [
5
5
  {
@@ -787,6 +787,82 @@
787
787
  "in": "description: 'a''--''b'\n",
788
788
  "out": "description: 'a''--''b'\n",
789
789
  "note": "modes.md §3.8.6 and §3.4: de-DE is a `-spaced` locale, so the dash would grow against a unit and the edge-growth rule discards it, as in fr. A second locale so that an implementation that does not split cannot pass on one cell alone."
790
+ },
791
+ {
792
+ "id": "de-de-protect-two-holes-dash",
793
+ "rule": "dashes",
794
+ "mode": "text",
795
+ "in": "${a} - ${b}",
796
+ "protect": [
797
+ {
798
+ "start": 0,
799
+ "end": 4
800
+ },
801
+ {
802
+ "start": 7,
803
+ "end": 11
804
+ }
805
+ ],
806
+ "out": "${a} – ${b}",
807
+ "protectOut": [
808
+ {
809
+ "start": 0,
810
+ "end": 4
811
+ },
812
+ {
813
+ "start": 7,
814
+ "end": 11
815
+ }
816
+ ],
817
+ "note": "modes.md §3.9.3: a token between two holes sees opaque content on both sides."
818
+ },
819
+ {
820
+ "id": "de-de-protect-dash-adjacent-growth-declined",
821
+ "rule": "dashes",
822
+ "mode": "text",
823
+ "in": "${a}--${b}",
824
+ "protect": [
825
+ {
826
+ "start": 0,
827
+ "end": 4
828
+ },
829
+ {
830
+ "start": 6,
831
+ "end": 10
832
+ }
833
+ ],
834
+ "out": "${a}--${b}",
835
+ "protectOut": [
836
+ {
837
+ "start": 0,
838
+ "end": 4
839
+ },
840
+ {
841
+ "start": 6,
842
+ "end": 10
843
+ }
844
+ ],
845
+ "note": "modes.md §3.9.4, accepted cost: '--' → ' – ' grows by one code point at both edges of its span, so the edge-growth rule (§3.4) discards it. The same string with no protect converts (§7.9)."
846
+ },
847
+ {
848
+ "id": "de-de-protect-quotes-around-hole",
849
+ "rule": "quotes",
850
+ "mode": "text",
851
+ "in": "Er sagte \"${name}\" zweimal.",
852
+ "protect": [
853
+ {
854
+ "start": 10,
855
+ "end": 17
856
+ }
857
+ ],
858
+ "out": "Er sagte „${name}“ zweimal.",
859
+ "protectOut": [
860
+ {
861
+ "start": 10,
862
+ "end": 17
863
+ }
864
+ ],
865
+ "note": "modes.md §3.9.3: the same pairing in a locale whose glyphs differ in shape."
790
866
  }
791
867
  ]
792
868
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "spec": "1.12.0",
2
+ "spec": "1.14.0",
3
3
  "locale": "el",
4
4
  "cases": [
5
5
  {
@@ -1,5 +1,5 @@
1
1
  {
2
- "spec": "1.12.0",
2
+ "spec": "1.14.0",
3
3
  "locale": "en-GB",
4
4
  "cases": [
5
5
  {
@@ -1388,6 +1388,94 @@
1388
1388
  "in": "(aside)'quoted' here",
1389
1389
  "out": "(aside)’quoted’ here",
1390
1390
  "note": "apostrophe.md §6 row 25 and §7 item 9 — case 2a's accepted cost, pinned so no port can narrow or widen it silently. The author meant a quotation and both marks now read as closing glyphs. It was mismatched before spec 1.5.0 too, in the other direction: 1.4.0 gave (aside)'quoted’ here, case 3 having curled the trailing mark while the leading one matched no case. `quotes` declines the leading mark because canOpen's right-test rejects a CLOSEISH left neighbour, so a quotation opening flush after a closing delimiter is exactly the shape it cannot pair, and two neighbours cannot separate that from a possessive."
1391
+ },
1392
+ {
1393
+ "id": "en-gb-protect-leading-hole-dash",
1394
+ "rule": "dashes",
1395
+ "mode": "text",
1396
+ "in": "${x} - Rules",
1397
+ "protect": [
1398
+ {
1399
+ "start": 0,
1400
+ "end": 4
1401
+ }
1402
+ ],
1403
+ "out": "${x} – Rules",
1404
+ "protectOut": [
1405
+ {
1406
+ "start": 0,
1407
+ "end": 4
1408
+ }
1409
+ ],
1410
+ "note": "modes.md §3.9.3: the same hole in a spaced-dash locale; the three-code-point token ' - ' becomes ' – ' without touching the hole."
1411
+ },
1412
+ {
1413
+ "id": "en-gb-protect-trailing-hole-dash",
1414
+ "rule": "dashes",
1415
+ "mode": "text",
1416
+ "in": "Rules - ${x}",
1417
+ "protect": [
1418
+ {
1419
+ "start": 8,
1420
+ "end": 12
1421
+ }
1422
+ ],
1423
+ "out": "Rules – ${x}",
1424
+ "protectOut": [
1425
+ {
1426
+ "start": 8,
1427
+ "end": 12
1428
+ }
1429
+ ],
1430
+ "note": "modes.md §3.9.3: a protected run at the end of the input is a marker too."
1431
+ },
1432
+ {
1433
+ "id": "en-gb-protect-icu-quoted-brace",
1434
+ "rule": "quotes",
1435
+ "mode": "text",
1436
+ "in": "Call it '{b}' now.",
1437
+ "protect": [
1438
+ {
1439
+ "start": 8,
1440
+ "end": 13
1441
+ }
1442
+ ],
1443
+ "out": "Call it '{b}' now.",
1444
+ "protectOut": [
1445
+ {
1446
+ "start": 8,
1447
+ "end": 13
1448
+ }
1449
+ ],
1450
+ "note": "polytypo/polytypo#14: in ICU MessageFormat an apostrophe before a brace is an escape. The caller protects the quoted brace including both apostrophes and they stay straight; without protect they become U+2018/U+2019."
1451
+ },
1452
+ {
1453
+ "id": "en-gb-protect-touching-ranges",
1454
+ "rule": "dashes",
1455
+ "mode": "text",
1456
+ "in": "a ${x}${y} - b",
1457
+ "protect": [
1458
+ {
1459
+ "start": 2,
1460
+ "end": 6
1461
+ },
1462
+ {
1463
+ "start": 6,
1464
+ "end": 10
1465
+ }
1466
+ ],
1467
+ "out": "a ${x}${y} – b",
1468
+ "protectOut": [
1469
+ {
1470
+ "start": 2,
1471
+ "end": 6
1472
+ },
1473
+ {
1474
+ "start": 6,
1475
+ "end": 10
1476
+ }
1477
+ ],
1478
+ "note": "modes.md §3.9.2: touching ranges are one protected run and give one marker."
1391
1479
  }
1392
1480
  ]
1393
1481
  }