polytypo 1.11.0 → 1.13.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.
- checksums.yaml +4 -4
- data/README.md +20 -0
- data/lib/polytypo/data/VERSION +1 -1
- data/lib/polytypo/data/fixtures/bg.json +253 -0
- data/lib/polytypo/data/fixtures/cs.json +1 -1
- data/lib/polytypo/data/fixtures/de-CH.json +1 -1
- data/lib/polytypo/data/fixtures/de-DE.json +77 -1
- data/lib/polytypo/data/fixtures/el.json +1 -1
- data/lib/polytypo/data/fixtures/en-GB.json +89 -1
- data/lib/polytypo/data/fixtures/en-US.json +450 -1
- data/lib/polytypo/data/fixtures/es.json +1 -1
- data/lib/polytypo/data/fixtures/fi.json +1 -1
- data/lib/polytypo/data/fixtures/fr-CA.json +1 -1
- data/lib/polytypo/data/fixtures/fr.json +41 -1
- data/lib/polytypo/data/fixtures/hr.json +253 -0
- data/lib/polytypo/data/fixtures/hu.json +264 -0
- data/lib/polytypo/data/fixtures/it.json +1 -1
- data/lib/polytypo/data/fixtures/locale-resolution.json +1 -1
- data/lib/polytypo/data/fixtures/nl.json +1 -1
- data/lib/polytypo/data/fixtures/pl.json +1 -1
- data/lib/polytypo/data/fixtures/pt-BR.json +1 -1
- data/lib/polytypo/data/fixtures/pt-PT.json +1 -1
- data/lib/polytypo/data/fixtures/ro.json +234 -0
- data/lib/polytypo/data/fixtures/ru.json +1 -1
- data/lib/polytypo/data/fixtures/sk.json +1 -1
- data/lib/polytypo/data/fixtures/sv.json +1 -1
- data/lib/polytypo/data/fixtures/tr.json +1 -1
- data/lib/polytypo/data/fixtures/uk.json +1 -1
- data/lib/polytypo/data/locales/bg.json +82 -0
- data/lib/polytypo/data/locales/hr.json +82 -0
- data/lib/polytypo/data/locales/hu.json +88 -0
- data/lib/polytypo/data/locales/registry.json +6 -2
- data/lib/polytypo/data/locales/ro.json +82 -0
- data/lib/polytypo/data/rules/analyze.md +16 -4
- data/lib/polytypo/data/rules/dashes.md +2 -1
- data/lib/polytypo/data/rules/modes.md +262 -9
- data/lib/polytypo/data/rules/order.json +1 -1
- data/lib/polytypo/data/rules/quotes.md +9 -0
- data/lib/polytypo/data/rules/ranges.md +6 -5
- data/lib/polytypo/data/schema/fixtures.schema.json +160 -18
- data/lib/polytypo/data/schema/locale.schema.json +2 -2
- data/lib/polytypo/engine/origin.rb +13 -1
- data/lib/polytypo/engine/protect.rb +122 -0
- data/lib/polytypo/modes/runner.rb +0 -1
- data/lib/polytypo/version.rb +1 -1
- data/lib/polytypo.rb +34 -19
- metadata +10 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5085a8645d4f2ef3be4dfc709d3be2ddeadee79c69b4a12c3fe3f2fa771f9099
|
|
4
|
+
data.tar.gz: e6994423f5fc58dc7142b27deae4dfb1504dbda181370c9d349feb9682a3672f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 90dcb32715c71d9305f6d71730409c232cdf13d920a0e2173444832c534c8a1195e7149d322484de45afad87a51b8c0fb22d0a30df8cd1408fbdf43331a14ebc
|
|
7
|
+
data.tar.gz: d365d8dec671abfb9230edb85509cc8a2ef0aaa87a6df4a6dd3bedbac2bacccea7752b9cd2b15cadaf9f7f023dbe49fa3ce3244ff16457534b7e8de97cb44394
|
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
|
data/lib/polytypo/data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.13.0
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
{
|
|
2
|
+
"spec": "1.13.0",
|
|
3
|
+
"locale": "bg",
|
|
4
|
+
"cases": [
|
|
5
|
+
{
|
|
6
|
+
"id": "bg-quotes-primary",
|
|
7
|
+
"rule": "quotes",
|
|
8
|
+
"mode": "text",
|
|
9
|
+
"in": "Той каза: \"не\" и си тръгна.",
|
|
10
|
+
"out": "Той каза: „не“ и си тръгна.",
|
|
11
|
+
"note": "ИБЕ, s.v. «кавички»: the base form is „…“ (U+201E, U+201C); the close is U+201C, not U+201D."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "bg-quotes-nested-same-pair",
|
|
15
|
+
"rule": "quotes",
|
|
16
|
+
"mode": "text",
|
|
17
|
+
"in": "Той каза: \"стихотворението \"Кафене Славия\" е хубаво\" и спря.",
|
|
18
|
+
"out": "Той каза: „стихотворението „Кафене Славия“ е хубаво“ и спря.",
|
|
19
|
+
"note": "ОПР т. 135.1.5, via ИБЕ: a quote inside a quote takes the same „ “ pair, so the inner level is not a different glyph."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "bg-quotes-nested-single-straight",
|
|
23
|
+
"rule": "quotes",
|
|
24
|
+
"mode": "text",
|
|
25
|
+
"in": "Той каза: \"стихотворението 'Кафене' е хубаво\".",
|
|
26
|
+
"out": "Той каза: „стихотворението „Кафене“ е хубаво“.",
|
|
27
|
+
"note": "A straight single mark inside a double quote becomes the secondary pair, which in bg equals the primary pair."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "bg-quotes-already-typeset-kept",
|
|
31
|
+
"rule": "quotes",
|
|
32
|
+
"mode": "text",
|
|
33
|
+
"in": "Той каза: „стихотворението „Кафене Славия“ е хубаво“ и спря.",
|
|
34
|
+
"out": "Той каза: „стихотворението „Кафене Славия“ е хубаво“ и спря.",
|
|
35
|
+
"note": "Already typeset at both levels: left as it is."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "bg-quotes-nest-at-end-declined",
|
|
39
|
+
"rule": "quotes",
|
|
40
|
+
"mode": "text",
|
|
41
|
+
"in": "Той каза: \"това е 'Славия'\".",
|
|
42
|
+
"out": "Той каза: \"това е ’Славия'\".",
|
|
43
|
+
"note": "Accepted miss: secondary equals primary, so a nest whose inner mark touches the outer one is declined by the quotes rule (quotes.md §3.2 V1, §3.5), and apostrophe then turns the inner opening mark into U+2019. Pinned as measured; the cost of the identical pair."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "bg-quotes-nest-at-end-double-declined",
|
|
47
|
+
"rule": "quotes",
|
|
48
|
+
"mode": "text",
|
|
49
|
+
"in": "\"Кафене \"Славия\"\"",
|
|
50
|
+
"out": "\"Кафене \"Славия\"\"",
|
|
51
|
+
"note": "Accepted miss: the ОПР т. 135.1.5 shape typed with straight marks stays entirely straight; the identical pair would put two like glyphs side by side."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "bg-quotes-nest-at-start-declined",
|
|
55
|
+
"rule": "quotes",
|
|
56
|
+
"mode": "text",
|
|
57
|
+
"in": "\"'b' a\"",
|
|
58
|
+
"out": "\"'b’ a\"",
|
|
59
|
+
"note": "Accepted miss: the inner mark at the start of the outer quote; the decline leaves a half-typeset result."
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "bg-quotes-decline-spreads",
|
|
63
|
+
"rule": "quotes",
|
|
64
|
+
"mode": "text",
|
|
65
|
+
"in": "\"x\" и \"a 'b'\"",
|
|
66
|
+
"out": "\"x\" и \"a ’b'\"",
|
|
67
|
+
"note": "Accepted miss: the decline is not local, the plain pair before the failing nest also stays straight."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "bg-quotes-no-inner-space",
|
|
71
|
+
"rule": "quotes",
|
|
72
|
+
"mode": "text",
|
|
73
|
+
"in": "„ не “",
|
|
74
|
+
"out": "„не“",
|
|
75
|
+
"note": "ИБЕ spacing article: no space inside the marks."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "bg-ellipsis-three-dots",
|
|
79
|
+
"rule": "ellipsis",
|
|
80
|
+
"mode": "text",
|
|
81
|
+
"in": "Чакай... какво?",
|
|
82
|
+
"out": "Чакай… какво?",
|
|
83
|
+
"note": "ИБЕ №2158: three dots, not four; the mark attaches to the preceding word."
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "bg-ellipsis-not-abbreviated",
|
|
87
|
+
"rule": "ellipsis",
|
|
88
|
+
"mode": "text",
|
|
89
|
+
"in": "Наистина?.. да",
|
|
90
|
+
"out": "Наистина?… да",
|
|
91
|
+
"note": "abbreviatedAfterTerminal is false: `?..` is a typing slip, not an abbreviated ellipsis (decision, no source)."
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "bg-dashes-parenthetical",
|
|
95
|
+
"rule": "dashes",
|
|
96
|
+
"mode": "text",
|
|
97
|
+
"in": "Утре - ако вали - няма да дойда.",
|
|
98
|
+
"out": "Утре – ако вали – няма да дойда.",
|
|
99
|
+
"note": "ИБЕ №572: a space before and after the long dash; U+2013 by decision."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "bg-dashes-existing-em-dash",
|
|
103
|
+
"rule": "dashes",
|
|
104
|
+
"mode": "text",
|
|
105
|
+
"in": "Утре — ако вали — няма да дойда.",
|
|
106
|
+
"out": "Утре – ако вали – няма да дойда.",
|
|
107
|
+
"note": "An authored em dash becomes the locale's en dash (the DGT handbook's U+2014 is house style)."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "bg-ranges-years-hyphen",
|
|
111
|
+
"rule": "ranges",
|
|
112
|
+
"mode": "text",
|
|
113
|
+
"in": "през 2000-2010 г. и I-II в.",
|
|
114
|
+
"out": "през 2000 – 2010 г. и I-II в.",
|
|
115
|
+
"note": "ranges.md §3: ОПР т. 103.4 prints «2000 – 2010 г.» with spaces; the Roman-numeral member is declined, so `I-II` stays.",
|
|
116
|
+
"rules": {
|
|
117
|
+
"ranges": true
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "bg-ranges-en-dash-gets-spaces",
|
|
122
|
+
"rule": "ranges",
|
|
123
|
+
"mode": "text",
|
|
124
|
+
"in": "2000–2010 г.",
|
|
125
|
+
"out": "2000 – 2010 г.",
|
|
126
|
+
"note": "ranges.md §3: a tight en dash is the pre-2012 form and takes the spaced form.",
|
|
127
|
+
"rules": {
|
|
128
|
+
"ranges": true
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"id": "bg-ranges-spaced-kept",
|
|
133
|
+
"rule": "ranges",
|
|
134
|
+
"mode": "text",
|
|
135
|
+
"in": "2000 – 2010 г.",
|
|
136
|
+
"out": "2000 – 2010 г.",
|
|
137
|
+
"note": "ranges.md §3: the spaced en dash is already the correct form.",
|
|
138
|
+
"rules": {
|
|
139
|
+
"ranges": true
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id": "bg-ranges-dates",
|
|
144
|
+
"rule": "ranges",
|
|
145
|
+
"mode": "text",
|
|
146
|
+
"in": "13.10. - 20.11.2018 г.",
|
|
147
|
+
"out": "13.10. – 20.11.2018 г.",
|
|
148
|
+
"note": "ranges.md §3: ОПР т. 109.4 prints «13.10. – 20.11.2018 г.».",
|
|
149
|
+
"rules": {
|
|
150
|
+
"ranges": true
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"id": "bg-ranges-word-hyphen-untouched",
|
|
155
|
+
"rule": "ranges",
|
|
156
|
+
"mode": "text",
|
|
157
|
+
"in": "Българо-руски речник",
|
|
158
|
+
"out": "Българо-руски речник",
|
|
159
|
+
"note": "ranges.md §3: a hyphenated word is not a digit range and is left alone.",
|
|
160
|
+
"rules": {
|
|
161
|
+
"ranges": true
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"id": "bg-hyphen-noop",
|
|
166
|
+
"rule": "hyphen",
|
|
167
|
+
"mode": "text",
|
|
168
|
+
"in": "северо-западен и по-добър",
|
|
169
|
+
"out": "северо-западен и по-добър",
|
|
170
|
+
"note": "ОПР т. 65–66 govern syllable breaks only; no list ships, nothing changes."
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"id": "bg-nbsp-units",
|
|
174
|
+
"rule": "nbsp",
|
|
175
|
+
"mode": "text",
|
|
176
|
+
"in": "100 км, 5 кг и 20 лв.",
|
|
177
|
+
"out": "100 км, 5 кг и 20 лв.",
|
|
178
|
+
"note": "ИБЕ №1601: a space separates the unit or abbreviation from its number."
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"id": "bg-nbsp-year-abbreviation",
|
|
182
|
+
"rule": "nbsp",
|
|
183
|
+
"mode": "text",
|
|
184
|
+
"in": "през 2020 г. беше",
|
|
185
|
+
"out": "през 2020 г. беше",
|
|
186
|
+
"note": "ИБЕ №1601: «2020 г.» with a space."
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"id": "bg-nbsp-percent-inert",
|
|
190
|
+
"rule": "nbsp",
|
|
191
|
+
"mode": "text",
|
|
192
|
+
"in": "5% и 5 %",
|
|
193
|
+
"out": "5% и 5 %",
|
|
194
|
+
"note": "ИБЕ №626 writes 5% without a space, so % is not a unit here and nothing is bound."
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"id": "bg-nbsp-single-letter-unit-inert",
|
|
198
|
+
"rule": "nbsp",
|
|
199
|
+
"mode": "text",
|
|
200
|
+
"in": "10 м и 5 с",
|
|
201
|
+
"out": "10 м и 5 с",
|
|
202
|
+
"note": "Single-letter symbols are excluded by decision, not by citation (ИБЕ №1601 writes «10 м» with a space): `с` is a Bulgarian preposition."
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "bg-nbsp-short-words-inert",
|
|
206
|
+
"rule": "nbsp",
|
|
207
|
+
"mode": "text",
|
|
208
|
+
"in": "в къщата и с приятел",
|
|
209
|
+
"out": "в къщата и с приятел",
|
|
210
|
+
"note": "afterShortWords ships empty: no source gives a rule for в, с, к, и."
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"id": "bg-nbsp-initials-unbound",
|
|
214
|
+
"rule": "nbsp",
|
|
215
|
+
"mode": "text",
|
|
216
|
+
"in": "Иван Вазов и И. Вазов",
|
|
217
|
+
"out": "Иван Вазов и И. Вазов",
|
|
218
|
+
"note": "initialBinding is none: no source states a rule on initials."
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"id": "bg-nbsp-no-space-before-question",
|
|
222
|
+
"rule": "nbsp",
|
|
223
|
+
"mode": "text",
|
|
224
|
+
"in": "Наистина ? Да !",
|
|
225
|
+
"out": "Наистина? Да!",
|
|
226
|
+
"note": "ИБЕ spacing article: no space before ? and !, so nothing is put back."
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"id": "bg-spaces-brackets",
|
|
230
|
+
"rule": "spaces",
|
|
231
|
+
"mode": "text",
|
|
232
|
+
"in": "Текст ( нормален ) остава .",
|
|
233
|
+
"out": "Текст (нормален) остава.",
|
|
234
|
+
"note": "spaces.md: brackets tighten, no space before the final stop."
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"id": "bg-symbols-copyright",
|
|
238
|
+
"rule": "symbols",
|
|
239
|
+
"mode": "text",
|
|
240
|
+
"in": "Copyright (c) 2026",
|
|
241
|
+
"out": "Copyright © 2026",
|
|
242
|
+
"note": "symbols rule, locale-neutral."
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"id": "bg-apostrophe-foreign-name",
|
|
246
|
+
"rule": "apostrophe",
|
|
247
|
+
"mode": "text",
|
|
248
|
+
"in": "Това е McDonald's",
|
|
249
|
+
"out": "Това е McDonald’s",
|
|
250
|
+
"note": "apostrophe rule, locale-neutral."
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"spec": "1.
|
|
2
|
+
"spec": "1.13.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.
|
|
2
|
+
"spec": "1.13.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
|
}
|