polytypo 1.6.0 → 1.6.1
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/lib/polytypo/data/.not-canonical +4 -0
- data/lib/polytypo/data/README.md +21 -6
- data/lib/polytypo/data/VERSION +1 -1
- 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 +1 -1
- data/lib/polytypo/data/fixtures/el.json +1 -1
- data/lib/polytypo/data/fixtures/en-GB.json +1 -1
- data/lib/polytypo/data/fixtures/en-US.json +1 -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 +1 -1
- 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/ru.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/registry.json +1 -1
- data/lib/polytypo/data/rules/apostrophe.md +56 -14
- data/lib/polytypo/data/rules/dashes.md +4 -1
- data/lib/polytypo/data/rules/locale-resolution.md +3 -3
- data/lib/polytypo/data/rules/order.json +1 -1
- data/lib/polytypo/data/rules/quotes.md +32 -5
- data/lib/polytypo/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0bb01ab8478817898277fc5b6d1f1654cc847a3f82ab1975e043e1a58409d2db
|
|
4
|
+
data.tar.gz: 559fdc9ca8756129e28d9762f2f3cc5666384f4c470960d84f181448dba56a0b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 69173cb92815bc03d120ea753d9cf1304c31786bdc576f7ac7f358679cbcac558b789d1d742622728d9cc23486de58b7185832e5e768c939032a24a7b8a94cca
|
|
7
|
+
data.tar.gz: ed92be4e7fe8d8d026fee4aaff03936553c4d086fe44a1eccf6bd8f890ba17c58710856e0b08a486722022d034ac432c623ccac28610c7c76f2994240e1e83c7
|
data/lib/polytypo/data/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Vendored spec subset
|
|
2
2
|
|
|
3
|
-
This directory is a manually-synced copy of
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`
|
|
3
|
+
This directory is a manually-synced copy of a subset of `polytypo/polytypo`'s canonical `spec/`:
|
|
4
|
+
`locales/`, `fixtures/`, the whole of `rules/`, `schema/`, `VERSION` and `UNICODE`. The gem and its
|
|
5
|
+
specs read only part of that — the locale and fixture data, `rules/order.json` and
|
|
6
|
+
`rules/dashes.md`; the other twelve rule documents are carried as the normative prose for the
|
|
7
|
+
behaviour the data drives, next to the data. It is **not** the canonical spec: `validate-spec.mjs`
|
|
8
|
+
lives only in `polytypo/polytypo`, and so does the authority — a change starts there and arrives
|
|
9
|
+
here by re-copying, never the other way round.
|
|
8
10
|
|
|
9
11
|
Named `lib/polytypo/data/`, not `vendor/polytypo-spec/` like the JS/Python ports: a Ruby
|
|
10
12
|
gemspec's `files` list can include any path directly, so there is no need for a separate
|
|
@@ -14,7 +16,20 @@ one copy, shipped as part of the gem's own `lib/` payload and loaded via `File.r
|
|
|
14
16
|
`__dir__` at runtime — never a network or external-filesystem read.
|
|
15
17
|
|
|
16
18
|
Editing a file here does not change the spec; it only drifts this copy from canonical. When
|
|
17
|
-
canonical's `spec/` changes, re-copy the affected files here.
|
|
19
|
+
canonical's `spec/` changes, re-copy the affected files here.
|
|
20
|
+
|
|
21
|
+
CI checks that it was done. `script/check-vendored-spec.sh` compares every file in this
|
|
22
|
+
directory against canonical `polytypo/polytypo` at tag `spec-v` + this directory's own
|
|
23
|
+
`VERSION`, and fails on any difference. Three details: the files this repository authors
|
|
24
|
+
itself are listed in `.not-canonical` and skipped; `locales/*.json` are compared with the
|
|
25
|
+
`sources` array dropped from both sides, which is the one field a vendored copy may
|
|
26
|
+
legitimately differ in; and a file here with no canonical counterpart is a failure, so a
|
|
27
|
+
canonical rename cannot pass unnoticed. Completeness is deliberately not checked — each
|
|
28
|
+
runtime vendors its own subset, and the subsets differ.
|
|
29
|
+
|
|
30
|
+
Before that check existed, this half of the tree went stale unnoticed in four of the five
|
|
31
|
+
ports at once: the data half is proved by the test suite, and nothing at all read the prose.
|
|
32
|
+
See `polytypo/polytypo` issue #56. How this vendoring will work
|
|
18
33
|
long-term (submodule, per-ecosystem spec package, or something else) is an open decision tracked
|
|
19
34
|
in `polytypo/polytypo`'s roadmap; this is the interim, manually-synced form — the same status
|
|
20
35
|
every other port's vendored copy has.
|
data/lib/polytypo/data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.6.
|
|
1
|
+
1.6.1
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"spec": "1.6.
|
|
2
|
+
"spec": "1.6.1",
|
|
3
3
|
"$comment": "Locale resolution input. Algorithm is specified in spec/rules/locale-resolution.md and is identical in every runtime — never delegate it to a platform locale-negotiation library. \"spec\" here must track spec/VERSION exactly — it is not itself the global version source; scripts/validate-spec.mjs enforces the match.",
|
|
4
4
|
"locales": [
|
|
5
5
|
"en-US",
|
|
@@ -571,12 +571,37 @@ layouts and in text pasted from older systems. Converting them is not authorised
|
|
|
571
571
|
gives `A ‘quoted’’s meaning`: the closing quotation mark and the possessive end up flush, and
|
|
572
572
|
at text size the pair reads as one double quote.
|
|
573
573
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
574
|
+
The mark case 2a adds is always U+2019; the mark it abuts is whichever `CLOSEDELIM` member
|
|
575
|
+
the locale closed with, and three of that class's four quotation members are reachable as a
|
|
576
|
+
locale's primary close, so this is **not an `en-GB` phenomenon**. Grouped by `quotes.primary.close`, seventeen of the
|
|
577
|
+
nineteen locales reach it through case 2a: `’’s` in `en-GB`; `”’s` in `en-US`, `fi`, `sv`,
|
|
578
|
+
`nl`, `pl`, `pt-BR` and `tr`; `»’s` in `de-CH`, `fr`, `fr-CA`, `ru`, `el`, `es`, `it`,
|
|
579
|
+
`pt-PT` and `uk`. Only the first two are plausibly confusable, and **which pairs those are is
|
|
580
|
+
a property of the glyph pair, not of the language** — so no existing locale field expresses
|
|
581
|
+
the distinction a separator rule would have to make.
|
|
582
|
+
|
|
583
|
+
**`de-DE` and `cs` look like this and are not it.** They close with U+201C, which §3.1 puts
|
|
584
|
+
in `OPENISH` and deliberately *not* in `CLOSEDELIM`, so `A „quoted“'s meaning` reaches its
|
|
585
|
+
U+2019 through **case 4** (leading elision: `OPENISH` left, `ALNUM` right), which is 0.4.1
|
|
586
|
+
vintage — the same U+201C-is-not-closeish asymmetry case 3a records for its own reason.
|
|
587
|
+
Measured on the published packages: 1.4.0 and 1.6.0 both emit `A „quoted“’s meaning`, while
|
|
588
|
+
`en-US` emits `A “quoted”'s meaning` on 1.4.0 and `A “quoted”’s meaning` on 1.6.0. The
|
|
589
|
+
`“’s` shape predates case 2a and is unchanged by it, so it is not this item's accepted cost.
|
|
590
|
+
|
|
591
|
+
**What the authority says, and what it does not.** The remedy and the character are both
|
|
592
|
+
named, but by a *CMOS Shop Talk* post — "When Quotation Marks and Apostrophes Collide",
|
|
593
|
+
published 2020-01-14, updated 2025-12-16 — and what that post describes
|
|
594
|
+
is the typesetting *CMOS* Online applies **to its own website**, not a rule stated for English
|
|
595
|
+
text. It enumerates the separator by code point (U+00A0, thin space U+2009, hair space U+200A
|
|
596
|
+
in print, U+202F online) and cross-references 18th ed. §6.11. **That cross-reference does not
|
|
597
|
+
survive a check against §6.11's own text, which this repository already holds.**
|
|
598
|
+
`spec/locales/en-US.json` quotes it verbatim: “When single quotation marks are nested within
|
|
599
|
+
double quotation marks, and two of the marks appear next to each other, a space between the
|
|
600
|
+
two marks, though not strictly required, aids legibility.” That is about *nested quotation
|
|
601
|
+
marks*, not an apostrophe, and it is permissive (“not strictly required”) rather than
|
|
602
|
+
prescriptive. The 18th edition's index files apostrophe adjacency somewhere else entirely,
|
|
603
|
+
at `apostrophes: other punctuation with, 6.126`; §6.126 and §6.128 are behind the
|
|
604
|
+
subscription and unread.
|
|
580
605
|
|
|
581
606
|
**polytypo emits the right character and inserts nothing.** This rule *cannot* insert: §1 and
|
|
582
607
|
§4 make every edit one code point replacing one code point at the same index, and that is
|
|
@@ -585,11 +610,28 @@ layouts and in text pasted from older systems. Converting them is not authorised
|
|
|
585
610
|
between them is unaddressed by every rule in `order.json` — recorded here as a decision
|
|
586
611
|
rather than left as an omission, in the standing of items 2 and 3.
|
|
587
612
|
|
|
588
|
-
**
|
|
589
|
-
|
|
590
|
-
apostrophe
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
613
|
+
**No separator is inserted, and that is now a decision rather than an open question
|
|
614
|
+
(2026-09-24).** No normative source addresses the ordering case 2a produces — closing mark,
|
|
615
|
+
then apostrophe, then `s`. What exists is one mark-order away from it and is not normative
|
|
616
|
+
anyway: the attested passage separates a title's *own* trailing apostrophe from a *following*
|
|
617
|
+
closing quotation mark (the song title *Ain't Misbehavin'* in single quotation marks —
|
|
618
|
+
apostrophe first), and it describes a publisher's rendering practice for its own website. The
|
|
619
|
+
paragraph that would govern the possessive ordering, `CMOS` §7.29 ("Possessive with
|
|
620
|
+
italicized or quoted terms"), is behind a subscription. `MHRA` was read in full and is silent;
|
|
621
|
+
Kotus names no code points at all; the Swedish genitive takes no apostrophe, so the shape is
|
|
622
|
+
not Swedish. **Operator decision: where no exact answer exists, choose one behaviour and pin
|
|
623
|
+
it rather than leave the rule undefined — consistency across the five runtimes is the
|
|
624
|
+
product, not conformance to a style guide nobody can read.** The pinned choice is *no
|
|
625
|
+
separator*: the marks sit flush.
|
|
626
|
+
|
|
627
|
+
**What makes that the cheap side of the choice.** The pair a reader could actually misread as
|
|
628
|
+
one mark is `’’`, and it is **unreachable from ordinary typing** — exhaustive sweep over the
|
|
629
|
+
alphabet `'` `"` `a` `s` space, 370,975 inputs to length 6 across all nineteen locales and
|
|
630
|
+
1,464,825 to length 8 across `en-GB`, `en-US` and `fi`: zero produce it. Two straight marks
|
|
631
|
+
are vetoed by `quotes` V1, and a straight `"…"` pair in a `NARROW`-primary locale is declined
|
|
632
|
+
by the certification gate for the same adjacency, so `’’` needs a closing mark that was
|
|
633
|
+
*already* U+2019 in the source. The pairs reachable from real input — `”’s`, `“’s`, `»’s`
|
|
634
|
+
— are legible as two marks. Inserting a space would mean a new `nbsp` insertion *position*
|
|
635
|
+
class, which `nbsp.md` §5's `I₆` and `quotes.md` §5's Lemma B would both have to be
|
|
636
|
+
re-derived for, in exchange for a cosmetic gain on text someone has already typeset. Recorded
|
|
637
|
+
as the standing answer; do not reopen it on a citation hunt.
|
|
@@ -900,7 +900,10 @@ never reaches a digit-flanked token at all.
|
|
|
900
900
|
### `el` — `parenthetical: "none"` (`range` is now [ranges.md](ranges.md)'s field, also `"none"`, not this rule's)
|
|
901
901
|
|
|
902
902
|
The first locale with `"none"` on **both** fields, so the rule is a **total no-op** for it in the
|
|
903
|
-
same provable sense `hyphen` is a no-op for a locale with empty lists.
|
|
903
|
+
same provable sense `hyphen` is a no-op for a locale with empty lists. It is no longer the only
|
|
904
|
+
one: `es` (spec 1.3.0) and `tr` (spec 1.6.0) are both-`none` too, each for its own reason and each
|
|
905
|
+
recorded in its own locale file. This section stays written about `el` because its two fields are
|
|
906
|
+
`"none"` for two *different* reasons, which is what makes it worth reading. Tokens are still
|
|
904
907
|
classified — §3.3's "a range token is never reconsidered as a parenthetical" still holds — but no
|
|
905
908
|
classification has an emission to make. The rows below are therefore all "no change" rows by
|
|
906
909
|
construction, and they are worth pinning precisely because nothing else in the suite exercises
|
|
@@ -193,7 +193,7 @@ that "no tag was supplied at all" is expressible as a fixture rather than only a
|
|
|
193
193
|
raise the coded error rather than a native `TypeError` — which matters because a `TypeError` is
|
|
194
194
|
not in the taxonomy (ARCHITECTURE.md §4.6) and would differ in each of the five runtimes.
|
|
195
195
|
|
|
196
|
-
Every row is a fixture, not a candidate: **
|
|
196
|
+
Every row is a fixture, not a candidate: **50 resolution cases run today**, covering these rows
|
|
197
197
|
and the malformed-tag rejections. `fixtures.schema.json` was extended with a case shape carrying
|
|
198
198
|
no `mode` and no `out`, whose expected result is a locale id or a thrown code. An earlier
|
|
199
199
|
revision of this paragraph said such rows "cannot be expressed in the existing fixture format";
|
|
@@ -210,11 +210,11 @@ that was true when written, and is why the schema was changed.
|
|
|
210
210
|
language polytypo does not support yet). I have mapped both to
|
|
211
211
|
`POLYTYPO_UNKNOWN_LOCALE` because inventing a code would change a documented contract.
|
|
212
212
|
Recommend adding `POLYTYPO_INVALID_LOCALE`; operator decision.
|
|
213
|
-
2. *(Closed.)* Resolution **is** fixture-covered:
|
|
213
|
+
2. *(Closed.)* Resolution **is** fixture-covered: 50 resolution cases run today. The gap this
|
|
214
214
|
item reported — that `fixtures.schema.json` could not express a case with no `mode`, no `out`
|
|
215
215
|
and an expected locale id or thrown code — was closed by extending the schema, and the §5
|
|
216
216
|
table's rows are those cases. (The item also miscounted the pipeline as seven rules; it is
|
|
217
|
-
|
|
217
|
+
nine — `hyphen` was added at order 35 and `ranges` at 37.)
|
|
218
218
|
|
|
219
219
|
3. **`sv-FI` (Finland Swedish) silently resolves to `sv`.** The two genuinely differ in some
|
|
220
220
|
conventions, and PLAN.md §7 already flags Swedish quote practice as uncertain. The
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"spec": "1.6.
|
|
2
|
+
"spec": "1.6.1",
|
|
3
3
|
"$comment": "Single source of truth for pipeline order. Rules run in ascending `order`. Disabling a rule removes it from the sequence and never reorders the rest. Rule ids are public API (see docs/ARCHITECTURE.md section 5). \"spec\" here must track spec/VERSION exactly — it is not itself the global version source; scripts/validate-spec.mjs enforces the match.",
|
|
4
4
|
"rules": [
|
|
5
5
|
{
|
|
@@ -595,14 +595,39 @@ typesets as `A ’stray mark here.` / `Then ‘inner’ text.`, and appending `S
|
|
|
595
595
|
re-pairs the first mark with the new one, making the middle pair nested and changing a line the
|
|
596
596
|
edit did not touch. Measured on 1.3.1 and unchanged by this veto.
|
|
597
597
|
|
|
598
|
-
**This is issue #53 §3,
|
|
598
|
+
**This is issue #53 §3, and as of 2026-09-24 it is decided rather than open: the behaviour
|
|
599
|
+
stands.** The report's own trigger lines are
|
|
599
600
|
`` `quotes`' locale data `` and `` `dashes`' own admissibility `` — plural possessives, exactly
|
|
600
601
|
this shape — so the cross-paragraph effect it documents in a real article is *not* repaired by
|
|
601
602
|
spec 1.4.0. Measured on this change, `markdown`/`commonmark`, `en-GB`:
|
|
602
603
|
`It is 'the `` `quotes`' `` locale data' here.` gives
|
|
603
604
|
`It is ‘the `` `quotes`’ `` locale data’ here.` — the plural possessive closes the quotation two
|
|
604
605
|
words early and the author's own closing mark is left to `apostrophe` as a stray U+2019. §1 of
|
|
605
|
-
that issue is closed
|
|
606
|
+
that issue is closed by the veto above; §3 is not, and is not going to be.
|
|
607
|
+
|
|
608
|
+
**Why §3 is decided and not merely unfixed.** Two measurements, both on the published 1.6.0
|
|
609
|
+
package. First, **the glyph at the possessive's own position is correct either way** — U+2019,
|
|
610
|
+
whether the mark is taken as a closing quotation mark or left unmatched for `apostrophe`. What
|
|
611
|
+
the defect costs is never the character a reader sees there; it is the *pairing it consumes*,
|
|
612
|
+
which is why the visible symptom always appears somewhere else (a stray U+0027 at the real
|
|
613
|
+
closing mark, or a middle paragraph re-nested from `‘ ’` to `“ ”`). Second, **separating the two
|
|
614
|
+
readings was implemented and measured, and it is worse.** The narrowest local veto that can do
|
|
615
|
+
it — decline a `NARROW` mark whose literal neighbour is `MARKER` and whose attaching `LETTER`
|
|
616
|
+
run is empty — breaks **7 of 2801 conformance cases**, five of them `tr` cases that are correct
|
|
617
|
+
today: `tr-html-span-boundary-suffix-declined`,
|
|
618
|
+
`tr-markdown-commonmark-span-boundary-suffix-declined`,
|
|
619
|
+
`tr-html-span-boundary-quotation-outside-the-span`,
|
|
620
|
+
`tr-html-span-boundary-non-ascii-initial-fragment` and `tr-html-span-boundary-ordinal-fragment`.
|
|
621
|
+
That is this section's own claim — no test over these neighbours can separate a plural
|
|
622
|
+
possessive from a closing mark after a span — turned from an argument into a number.
|
|
623
|
+
|
|
624
|
+
**Operator decision (2026-09-24): where no exact answer exists, choose one behaviour and pin it
|
|
625
|
+
rather than leave the rule undefined.** Five runtimes agreeing byte-for-byte is the product; an
|
|
626
|
+
undecided rule is worse than an arbitrary decided one. The pinned behaviour is the one specified
|
|
627
|
+
here and fixtured at §6 row S5. A future change would have to be a **pairing-preference**
|
|
628
|
+
mechanism, not a classification test, and §3.3's three-outcome partition is the premise §5's
|
|
629
|
+
certification theorem rests on — so it replaces that premise rather than extending it, and needs
|
|
630
|
+
its own idempotency argument. Nobody should spend that on this without a new reason.
|
|
606
631
|
|
|
607
632
|
**V1 — same-V1-identity adjacency veto** (both widths):
|
|
608
633
|
|
|
@@ -1330,7 +1355,7 @@ what a port should be able to re-derive from §3.2 alone.
|
|
|
1330
1355
|
| S2 | `fr` | `Il dit 'l'<em>idée</em> est bonne.' Fin.` | `Il dit «⍽l’<em>idée</em> est bonne.⍽» Fin.` | the mirror direction: `Rlit` is the `MARKER`, the run left of the mark is `l`, a cited `before` entry. Through 1.3.1 this gave `Il dit «⍽l⍽»<em>idée</em> est bonne.' Fin.` — guillemets around one letter, the real closing mark abandoned |
|
|
1331
1356
|
| S3 | `fr` | `Il dit 'jusqu'<em>ici</em> tout va bien.' Fin.` | `Il dit «⍽jusqu’<em>ici</em> tout va bien.⍽» Fin.` | the run is compared **whole**: it is `jusqu`, so an entry `qu` could not match it. This is why `jusqu`, `lorsqu`, `puisqu` and `quoiqu` are listed in their own right |
|
|
1332
1357
|
| S4 | `fr` | `Il dit <em>'oui'</em> ici.` | `Il dit <em>«⍽oui⍽»</em> ici.` | the negative control the mechanism exists to preserve. `Llit` is the `MARKER` here too — what separates this from S2 is only that `oui` is not a listed fragment |
|
|
1333
|
-
| S5 | `en-GB` | `` He says 'avoid `xs`' printer.' Done. `` | `` He says ‘avoid `xs`’ printer.' Done. `` | **not closed.** The plural possessive's run is empty, so neither test applies, and these code points are also a closing mark after a span. The second mark takes the pairing, the third is abandoned as U+0027. §4, §7 item 10, issue #54 |
|
|
1358
|
+
| S5 | `en-GB` | `` He says 'avoid `xs`' printer.' Done. `` | `` He says ‘avoid `xs`’ printer.' Done. `` | **not closed.** The plural possessive's run is empty, so neither test applies, and these code points are also a closing mark after a span. The second mark takes the pairing, the third is abandoned as U+0027. **Decided behaviour, not a pending fix** — §3.2. §4, §7 item 10, issue #54 |
|
|
1334
1359
|
| S6 | `fr` | `Il dit 'QU'<em>il</em> vienne.' Fin.` | `Il dit «⍽QU⍽»<em>il</em> vienne.' Fin.` | **not closed.** The fold reaches only the run's first code point, and only ASCII `A`–`Z`, so `QU` does not match `qu` and the inversion survives. Same limit as the listed veto's context words |
|
|
1335
1360
|
| S7 | `en-US` | `He said <em>'s'</em> loudly.` | `He said <em>’s’</em> loudly.` | the accepted false positive: a quotation inside a span whose whole content is a listed fragment. Narrower than the medial-`n` veto's own accepted `The letter 'n' is common.`, since it needs the boundary as well |
|
|
1336
1361
|
| S8 | `nl` | `Hij zegt 'ik kom <em>vroeg </em>'s avonds terug.' Klaar.` | `Hij zegt “ik kom <em>vroeg </em>’s avonds terug.” Klaar.` | `'s` is a word-*initial* omission, so its run lies to the mark's right and the entry is an `after` one — the clearest case for reading both lists positionally (§2) |
|
|
@@ -1480,7 +1505,8 @@ Ordered by how much this matters.
|
|
|
1480
1505
|
rule. Two shapes stay open in **every** locale, both for the same reason: the attaching
|
|
1481
1506
|
fragment is not there to read. A plural possessive after a span (`` `xs`' ``) has an empty
|
|
1482
1507
|
run and is byte-identical to a closing mark after a span (§4) — **this is issue #53 §3, the
|
|
1483
|
-
cross-paragraph witness that motivated the report
|
|
1508
|
+
cross-paragraph witness that motivated the report, and it is decided rather than open — §3.2
|
|
1509
|
+
gives the two measurements and issue #54 records the close**; and a fragment written in
|
|
1484
1510
|
capitals (`QU'<em>il</em>`) fails the first-code-point folding this rule shares with item 8's
|
|
1485
1511
|
listed veto. Neither is a candidate for a wider mechanism: widening the folding is
|
|
1486
1512
|
`ARCHITECTURE.md` §4.4's banned territory, and the plural possessive has no local evidence at
|
|
@@ -1539,7 +1565,8 @@ consulted only when the mark is flush against an inline span boundary. It closes
|
|
|
1539
1565
|
§1** — a possessive or elision written against a span (`` `x`'s ``, `l'<em>idée</em>`) was
|
|
1540
1566
|
classified as a quotation candidate, took the pairing from the author's own mark inside a
|
|
1541
1567
|
quotation, and inverted the pair in every locale. **It does not close issue #53 §3**, the
|
|
1542
|
-
cross-paragraph damage that motivated the report, which
|
|
1568
|
+
cross-paragraph damage that motivated the report, which was tracked separately as issue #54 and
|
|
1569
|
+
is decided rather than fixed (2026-09-24, §3.2): that witness is a *plural* possessive after a
|
|
1543
1570
|
span, and §3.2 records why no veto over these neighbours can reach it. The simpler design — letting the boundary marker satisfy the
|
|
1544
1571
|
medial-elision veto's `ALNUM` test — was implemented, measured, and rejected before any release:
|
|
1545
1572
|
it breaks a quotation that legitimately begins or ends at a span boundary, including the
|
data/lib/polytypo/version.rb
CHANGED
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.6.
|
|
4
|
+
version: 1.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Iurii Rogulia
|
|
@@ -35,6 +35,7 @@ files:
|
|
|
35
35
|
- LICENSE
|
|
36
36
|
- README.md
|
|
37
37
|
- lib/polytypo.rb
|
|
38
|
+
- lib/polytypo/data/.not-canonical
|
|
38
39
|
- lib/polytypo/data/README.md
|
|
39
40
|
- lib/polytypo/data/UNICODE
|
|
40
41
|
- lib/polytypo/data/VERSION
|