polytypo 1.2.0 → 1.3.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 +33 -1
- data/lib/polytypo/data/VERSION +1 -1
- data/lib/polytypo/data/fixtures/cs.json +161 -0
- data/lib/polytypo/data/fixtures/de-CH.json +1 -1
- data/lib/polytypo/data/fixtures/de-DE.json +195 -6
- data/lib/polytypo/data/fixtures/el.json +1 -1
- data/lib/polytypo/data/fixtures/en-GB.json +12 -1
- data/lib/polytypo/data/fixtures/en-US.json +626 -1
- data/lib/polytypo/data/fixtures/es.json +193 -0
- data/lib/polytypo/data/fixtures/fi.json +1 -1
- data/lib/polytypo/data/fixtures/fr-CA.json +25 -1
- data/lib/polytypo/data/fixtures/fr.json +176 -1
- data/lib/polytypo/data/fixtures/it.json +161 -0
- data/lib/polytypo/data/fixtures/locale-resolution.json +76 -4
- data/lib/polytypo/data/fixtures/nl.json +121 -0
- data/lib/polytypo/data/fixtures/pl.json +137 -0
- data/lib/polytypo/data/fixtures/pt-BR.json +156 -0
- data/lib/polytypo/data/fixtures/pt-PT.json +156 -0
- data/lib/polytypo/data/fixtures/ru.json +23 -1
- data/lib/polytypo/data/fixtures/sv.json +1 -1
- data/lib/polytypo/data/fixtures/uk.json +153 -0
- data/lib/polytypo/data/locales/cs.json +90 -0
- data/lib/polytypo/data/locales/de-DE.json +7 -2
- data/lib/polytypo/data/locales/en-US.json +3 -3
- data/lib/polytypo/data/locales/es.json +111 -0
- data/lib/polytypo/data/locales/fr-CA.json +7 -1
- data/lib/polytypo/data/locales/fr.json +7 -1
- data/lib/polytypo/data/locales/it.json +95 -0
- data/lib/polytypo/data/locales/nl.json +84 -0
- data/lib/polytypo/data/locales/pl.json +96 -0
- data/lib/polytypo/data/locales/pt-BR.json +82 -0
- data/lib/polytypo/data/locales/pt-PT.json +84 -0
- data/lib/polytypo/data/locales/registry.json +23 -3
- data/lib/polytypo/data/locales/ru.json +2 -2
- data/lib/polytypo/data/locales/uk.json +130 -0
- data/lib/polytypo/data/rules/analyze.md +157 -0
- data/lib/polytypo/data/rules/apostrophe.md +432 -0
- data/lib/polytypo/data/rules/dashes.md +128 -37
- data/lib/polytypo/data/rules/ellipsis.md +271 -0
- data/lib/polytypo/data/rules/hyphen.md +353 -0
- data/lib/polytypo/data/rules/locale-resolution.md +239 -0
- data/lib/polytypo/data/rules/modes.md +1281 -0
- data/lib/polytypo/data/rules/nbsp.md +1157 -0
- data/lib/polytypo/data/rules/order.json +11 -11
- data/lib/polytypo/data/rules/pipeline-idempotency.md +605 -0
- data/lib/polytypo/data/rules/quotes.md +1324 -0
- data/lib/polytypo/data/rules/ranges.md +489 -0
- data/lib/polytypo/data/rules/spaces.md +649 -0
- data/lib/polytypo/data/rules/symbols.md +540 -0
- data/lib/polytypo/data/schema/fixtures.schema.json +18 -3
- data/lib/polytypo/engine/origin.rb +75 -0
- data/lib/polytypo/engine/pipeline.rb +72 -1
- data/lib/polytypo/engine/rules/dash_shared.rb +85 -3
- data/lib/polytypo/engine/rules/dashes.rb +4 -1
- data/lib/polytypo/engine/rules/nbsp.rb +43 -7
- data/lib/polytypo/engine/rules/ranges.rb +24 -20
- data/lib/polytypo/errors.rb +3 -0
- data/lib/polytypo/modes/runner.rb +17 -0
- data/lib/polytypo/modes/spans.rb +30 -2
- data/lib/polytypo/modes/yaml.rb +312 -0
- data/lib/polytypo/version.rb +1 -1
- data/lib/polytypo.rb +126 -15
- metadata +31 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"spec": "1.
|
|
2
|
+
"spec": "1.3.0",
|
|
3
3
|
"locale": "en-US",
|
|
4
4
|
"cases": [
|
|
5
5
|
{
|
|
@@ -1866,6 +1866,631 @@
|
|
|
1866
1866
|
"in": "Use .<b>NET</b> today",
|
|
1867
1867
|
"out": "Use.<b>NET</b> today",
|
|
1868
1868
|
"note": "spaces.md §3.4 word-start clause (spec 1.2.0): the code point after the dot is the −1 span boundary marker, which is neither a LETTER nor an ASCII digit (modes.md §3.3), so the dot counts as terminal and the space before it is deleted."
|
|
1869
|
+
},
|
|
1870
|
+
{
|
|
1871
|
+
"id": "en-us-markdown-mdx-frontmatter",
|
|
1872
|
+
"rule": "quotes",
|
|
1873
|
+
"mode": "markdown",
|
|
1874
|
+
"dialect": "mdx",
|
|
1875
|
+
"in": "---\ntitle: \"Une note\"\n---\n\n<Callout>Body \"quotes\" here</Callout>\n",
|
|
1876
|
+
"out": "---\ntitle: \"Une note\"\n---\n\n<Callout>Body “quotes” here</Callout>\n",
|
|
1877
|
+
"note": "modes.md §3.7.3: frontmatter is skipped whole under \"mdx\" too, not only under \"commonmark\" (compare en-us-markdown-commonmark-frontmatter, the same block in the other dialect). Frontmatter followed by JSX is the realistic MDX document shape, and the JSX element's children are processable prose per the same section."
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
"id": "en-us-markdown-mdx-frontmatter-abuts-content",
|
|
1881
|
+
"rule": "quotes",
|
|
1882
|
+
"mode": "markdown",
|
|
1883
|
+
"dialect": "mdx",
|
|
1884
|
+
"in": "---\ntitle: \"Une note\"\n---\n<Callout>Body \"quotes\" here</Callout>\n",
|
|
1885
|
+
"out": "---\ntitle: \"Une note\"\n---\n<Callout>Body “quotes” here</Callout>\n",
|
|
1886
|
+
"note": "modes.md §3.7.3: the skipped block ends at its closing delimiter, so content on the very next line with no blank line between is ordinary MDX and converts. Pins that the skip is delimited by the block itself and not by a following blank line."
|
|
1887
|
+
},
|
|
1888
|
+
{
|
|
1889
|
+
"id": "en-us-markdown-commonmark-frontmatter-toml",
|
|
1890
|
+
"rule": "quotes",
|
|
1891
|
+
"mode": "markdown",
|
|
1892
|
+
"dialect": "commonmark",
|
|
1893
|
+
"in": "+++\ntitle = \"Une note\"\n+++\n\nBody \"quotes\" here.\n",
|
|
1894
|
+
"out": "+++\ntitle = \"Une note\"\n+++\n\nBody “quotes” here.\n",
|
|
1895
|
+
"note": "modes.md §3.7.3 names both delimiters: a frontmatter block is delimited by --- (YAML) or +++ (TOML) and is skipped whole either way. The machine-read TOML field keeps its straight quotes while body prose converts."
|
|
1896
|
+
},
|
|
1897
|
+
{
|
|
1898
|
+
"id": "en-us-markdown-commonmark-frontmatter-unterminated",
|
|
1899
|
+
"rule": "quotes",
|
|
1900
|
+
"mode": "markdown",
|
|
1901
|
+
"dialect": "commonmark",
|
|
1902
|
+
"in": "---\ntitle: \"Unclosed\"\n\nBody \"quotes\" here.\n",
|
|
1903
|
+
"out": "---\ntitle: “Unclosed”\n\nBody “quotes” here.\n",
|
|
1904
|
+
"note": "modes.md §3.7.3 skips a frontmatter block; an opening delimiter with no closing one is not a block. The leading --- is then an ordinary thematic break and everything after it is prose, so the metadata-looking line converts like any other paragraph. Pinned so the skip cannot be widened into \"anything after a leading ---\"."
|
|
1905
|
+
},
|
|
1906
|
+
{
|
|
1907
|
+
"id": "en-us-ranges-closed-up-currency",
|
|
1908
|
+
"rule": "ranges",
|
|
1909
|
+
"mode": "text",
|
|
1910
|
+
"in": "$15-$20",
|
|
1911
|
+
"out": "$15–$20",
|
|
1912
|
+
"rules": {
|
|
1913
|
+
"ranges": true
|
|
1914
|
+
},
|
|
1915
|
+
"note": "ranges.md §3.2a (spec 1.3.0): both members repeat the same closed-up symbol, so the walk consumes the U+0024 on the right flank and the token is a range candidate. Chicago 9.19 — \"an abbreviation or symbol is repeated if it is closed up to the number\" — makes `$15–$20` the form, and before 1.3.0 this input was left with a hyphen, which no reading of that source allows. The U+2060 pair is ranges.md §3.3.1's tight binding and is invisible on screen: review this row in spec/fixtures/.escaped/."
|
|
1916
|
+
},
|
|
1917
|
+
{
|
|
1918
|
+
"id": "en-us-ranges-closed-up-percent",
|
|
1919
|
+
"rule": "ranges",
|
|
1920
|
+
"mode": "text",
|
|
1921
|
+
"in": "35%-50%",
|
|
1922
|
+
"out": "35%–50%",
|
|
1923
|
+
"rules": {
|
|
1924
|
+
"ranges": true
|
|
1925
|
+
},
|
|
1926
|
+
"note": "ranges.md §3.2a (spec 1.3.0): the mirror of the currency case — the closed-up symbol is a SUFFIX, so the walk moves the LEFT flank and matches it against the outer symbol after Rrun. `35%–50%` is the literal example in the Chicago sentence §3.2a quotes; the rule is closed-up versus spaced, not currency versus unit."
|
|
1927
|
+
},
|
|
1928
|
+
{
|
|
1929
|
+
"id": "en-us-ranges-closed-up-degree",
|
|
1930
|
+
"rule": "ranges",
|
|
1931
|
+
"mode": "text",
|
|
1932
|
+
"in": "15°-20°",
|
|
1933
|
+
"out": "15°–20°",
|
|
1934
|
+
"rules": {
|
|
1935
|
+
"ranges": true
|
|
1936
|
+
},
|
|
1937
|
+
"note": "ranges.md §3.2a (spec 1.3.0): U+00B0 is in CLOSED-SYMBOL on the same ground as U+0024 and U+0025 — a symbol conventionally written closed up to a number. Pinned because the set is a literal enumeration, not a Unicode category test, so every member needs a case or the enumeration drifts per runtime."
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
"id": "en-us-ranges-closed-up-mismatched",
|
|
1941
|
+
"rule": "ranges",
|
|
1942
|
+
"mode": "text",
|
|
1943
|
+
"in": "$15-€20",
|
|
1944
|
+
"out": "$15-€20",
|
|
1945
|
+
"rules": {
|
|
1946
|
+
"ranges": true
|
|
1947
|
+
},
|
|
1948
|
+
"note": "ranges.md §3.2a (spec 1.3.0): the symbols must be the SAME code point. This is a currency conversion, not a range, and converting its hyphen would assert something false. The walk is not taken, so the right flank stays a non-DIGIT and the token is not a range candidate at all — it remains `dashes`' concern, exactly as before 1.3.0."
|
|
1949
|
+
},
|
|
1950
|
+
{
|
|
1951
|
+
"id": "en-us-ranges-closed-up-half-written",
|
|
1952
|
+
"rule": "ranges",
|
|
1953
|
+
"mode": "text",
|
|
1954
|
+
"in": "15-$20",
|
|
1955
|
+
"out": "15-$20",
|
|
1956
|
+
"rules": {
|
|
1957
|
+
"ranges": true
|
|
1958
|
+
},
|
|
1959
|
+
"note": "ranges.md §3.2a (spec 1.3.0): an inner symbol with no matching outer symbol on the opposite member. Declined for the same reason as the mismatched case, and this is the row that proves the match is required in BOTH directions rather than only when both members carry a symbol."
|
|
1960
|
+
},
|
|
1961
|
+
{
|
|
1962
|
+
"id": "en-us-ranges-closed-up-multi-code-point",
|
|
1963
|
+
"rule": "ranges",
|
|
1964
|
+
"mode": "text",
|
|
1965
|
+
"in": "US$15-US$20",
|
|
1966
|
+
"out": "US$15-US$20",
|
|
1967
|
+
"rules": {
|
|
1968
|
+
"ranges": true
|
|
1969
|
+
},
|
|
1970
|
+
"note": "ranges.md §3.2a and §7.7 (spec 1.3.0): the walk consumes at most one code point per side, and the mechanism here is CANDIDACY, not a guard — `cp[R]` is `U`, which is not in CLOSED-SYMBOL, so no walk is taken and the flank is simply not a DIGIT. The half-written `US$15-$20` IS a candidate and is declined by G1 instead, because `before` reads past the matched U+0024 and finds `S`; see en-us-ranges-closed-up-letter-prefix for that half."
|
|
1971
|
+
},
|
|
1972
|
+
{
|
|
1973
|
+
"id": "en-us-ranges-closed-up-elided-unchanged",
|
|
1974
|
+
"rule": "ranges",
|
|
1975
|
+
"mode": "text",
|
|
1976
|
+
"in": "$15-20 and 15-20%",
|
|
1977
|
+
"out": "$15–20 and 15–20%",
|
|
1978
|
+
"rules": {
|
|
1979
|
+
"ranges": true
|
|
1980
|
+
},
|
|
1981
|
+
"note": "ranges.md §3.2a (spec 1.3.0): the elided forms, where the symbol is written once. They converted before 1.3.0 and must keep converting — the Chicago answer §3.2a quotes calls them acceptable variants, and this row is the regression witness that adding the closed-up walk did not make the outer symbol a requirement."
|
|
1982
|
+
},
|
|
1983
|
+
{
|
|
1984
|
+
"id": "en-us-ranges-closed-up-spaced-token",
|
|
1985
|
+
"rule": "ranges",
|
|
1986
|
+
"mode": "text",
|
|
1987
|
+
"in": "$15 - $20",
|
|
1988
|
+
"out": "$15–$20",
|
|
1989
|
+
"rules": {
|
|
1990
|
+
"ranges": true
|
|
1991
|
+
},
|
|
1992
|
+
"note": "ranges.md §3.2a (spec 1.3.0): the spaced form of the same token. Before 1.3.0 this was `dashes`' token and became `$15—$20` (en-US's em-tight parenthetical form) with DEFAULT options; now it is a range candidate, so it converts to the range form when `ranges` is on and is a no-op when it is off. See en-us-dashes-closed-up-range-declined for the other half of that pair."
|
|
1993
|
+
},
|
|
1994
|
+
{
|
|
1995
|
+
"id": "en-us-dashes-closed-up-range-declined",
|
|
1996
|
+
"rule": "dashes",
|
|
1997
|
+
"mode": "text",
|
|
1998
|
+
"in": "$15 - $20",
|
|
1999
|
+
"out": "$15 - $20",
|
|
2000
|
+
"note": "ranges.md §3.2a and dashes.md §1 (spec 1.3.0): the ACCEPTED COST of widening range candidacy. With default options this input produced `$15—$20` through spec 1.2.0; a range candidate is declined by `dashes` unconditionally, whether or not `ranges` is enabled, so it is now a no-op. That is the behaviour `$15 - 20` has had since spec 0.5.0 — the change makes the two consistent."
|
|
2001
|
+
},
|
|
2002
|
+
{
|
|
2003
|
+
"id": "en-us-ranges-closed-up-letter-prefix",
|
|
2004
|
+
"rule": "ranges",
|
|
2005
|
+
"mode": "text",
|
|
2006
|
+
"in": "US$15-$20",
|
|
2007
|
+
"out": "US$15-$20",
|
|
2008
|
+
"rules": {
|
|
2009
|
+
"ranges": true
|
|
2010
|
+
},
|
|
2011
|
+
"note": "ranges.md §3.2a (spec 1.3.0): the other half of the multi-code-point case. Here the right walk DOES match — the outer symbol in front of `15` is the same U+0024 — so the token is a range candidate and reaches the guards, where G1 declines it: `before` reads past the matched symbol and finds `S`, a LETTER. Pinned because §3.2a claims two different mechanisms for two inputs that look alike."
|
|
2012
|
+
},
|
|
2013
|
+
{
|
|
2014
|
+
"id": "en-us-ranges-closed-up-joiner-wrapped-hyphen",
|
|
2015
|
+
"rule": "ranges",
|
|
2016
|
+
"mode": "text",
|
|
2017
|
+
"in": "$15-$20",
|
|
2018
|
+
"out": "$15–$20",
|
|
2019
|
+
"rules": {
|
|
2020
|
+
"ranges": true
|
|
2021
|
+
},
|
|
2022
|
+
"note": "ranges.md §3.1 and §3.2a, via dashes.md §3.2a (spec 1.3.0): the ONLY input that separates the amended re-entry condition from the unamended one. ranges.md §3.1 borrows the joiner-crossing walk from dashes.md §3.2a, and before 1.3.0 that walk required DIGIT on both effective neighbours — with a symbol there, a hyphen an author typed between an existing U+2060 pair fell through to \"joiner crossed in any other configuration: emit nothing\". Without this case a port could skip the amendment and pass the whole suite."
|
|
2023
|
+
},
|
|
2024
|
+
{
|
|
2025
|
+
"id": "en-us-ranges-closed-up-both-flanks",
|
|
2026
|
+
"rule": "ranges",
|
|
2027
|
+
"mode": "text",
|
|
2028
|
+
"in": "%15%-%20%",
|
|
2029
|
+
"out": "%15%–%20%",
|
|
2030
|
+
"rules": {
|
|
2031
|
+
"ranges": true
|
|
2032
|
+
},
|
|
2033
|
+
"note": "ranges.md §3.2a (spec 1.3.0): both flanks are in CLOSED-SYMBOL, which is the shape that makes the evaluation order observable. §3.2a decides both sides from the ORIGINAL L and R simultaneously, so both walks are taken and both match; a left-then-right or right-then-left reading would leave one side's `Lrun` undefined and decline. Not idiomatic text — pinned purely to make the evaluation model conformance-testable."
|
|
2034
|
+
},
|
|
2035
|
+
{
|
|
2036
|
+
"id": "en-us-ranges-closed-up-symbol-set-cents-pounds",
|
|
2037
|
+
"rule": "ranges",
|
|
2038
|
+
"mode": "text",
|
|
2039
|
+
"in": "¢15-¢20 and ¤15-¤20 and ¥15-¥20",
|
|
2040
|
+
"out": "¢15–¢20 and ¤15–¤20 and ¥15–¥20",
|
|
2041
|
+
"rules": {
|
|
2042
|
+
"ranges": true
|
|
2043
|
+
},
|
|
2044
|
+
"note": "ranges.md §3.2a (spec 1.3.0): CLOSED-SYMBOL is a literal enumeration, not a Unicode category test, so each member needs a case or a port enumerating only the obvious few passes the whole suite. U+00A2, U+00A4 and U+00A5; U+0024 and U+20AC have their own cases, U+00A3 is pinned in en-GB."
|
|
2045
|
+
},
|
|
2046
|
+
{
|
|
2047
|
+
"id": "en-us-ranges-closed-up-symbol-set-permille",
|
|
2048
|
+
"rule": "ranges",
|
|
2049
|
+
"mode": "text",
|
|
2050
|
+
"in": "15‰-20‰ and 15‱-20‱",
|
|
2051
|
+
"out": "15‰–20‰ and 15‱–20‱",
|
|
2052
|
+
"rules": {
|
|
2053
|
+
"ranges": true
|
|
2054
|
+
},
|
|
2055
|
+
"note": "ranges.md §3.2a (spec 1.3.0): U+2030 and U+2031, the per-mille and per-ten-thousand signs, in the suffix position. Same reason as the currency case — the set is an enumeration and every member is part of the contract."
|
|
2056
|
+
},
|
|
2057
|
+
{
|
|
2058
|
+
"id": "en-us-dashes-t1-closed-up-symbol-unaffected",
|
|
2059
|
+
"rule": "dashes",
|
|
2060
|
+
"mode": "text",
|
|
2061
|
+
"in": "price--$50--drop",
|
|
2062
|
+
"out": "price—$50—drop",
|
|
2063
|
+
"note": "dashes.md §3.2 step 8 (spec 1.3.0): the boundary of the accepted cost, with DEFAULT options. T1 applies only when the chosen form is `-spaced`; `en-US` sets `em-tight`, so this input is untouched by the amendment and still converts exactly as it did through spec 1.2.0. Pinned because the alternative repair — putting CLOSED-SYMBOL in the cluster guard's alphabet (§3.2 step 7) — is unconditional and would have made this a no-op in every locale. Without this case a port could take that shortcut and pass the suite."
|
|
2064
|
+
},
|
|
2065
|
+
{
|
|
2066
|
+
"id": "en-us-ranges-closed-up-block-member",
|
|
2067
|
+
"rule": "ranges",
|
|
2068
|
+
"mode": "text",
|
|
2069
|
+
"in": "₹15-₹20 and ₴100-₴200",
|
|
2070
|
+
"out": "₹15–₹20 and ₴100–₴200",
|
|
2071
|
+
"rules": {
|
|
2072
|
+
"ranges": true
|
|
2073
|
+
},
|
|
2074
|
+
"note": "ranges.md §3.2a (spec 1.3.0): U+20B9 and U+20B4, members of the U+20A0–U+20CF block that are NOT among the code points any other fixture names. CLOSED-SYMBOL is the whole block by its bounds, so a port that enumerates only the symbols it saw in fixtures — dollar, euro, the Latin-1 four — passes every other case and fails this one."
|
|
2075
|
+
},
|
|
2076
|
+
{
|
|
2077
|
+
"id": "en-us-ranges-closed-up-not-a-member",
|
|
2078
|
+
"rule": "ranges",
|
|
2079
|
+
"mode": "text",
|
|
2080
|
+
"in": "֏15-֏20 and ¥15-¥20",
|
|
2081
|
+
"out": "֏15-֏20 and ¥15-¥20",
|
|
2082
|
+
"rules": {
|
|
2083
|
+
"ranges": true
|
|
2084
|
+
},
|
|
2085
|
+
"note": "ranges.md §3.2a (spec 1.3.0): the NEGATIVE side of the enumeration. U+058F (Armenian dram) and U+FFE5 (fullwidth yen) are currency signs in Unicode's own classification and are deliberately NOT in CLOSED-SYMBOL, which is a literal code-point set precisely so that no runtime has to agree with another about a Unicode category. A port implementing the set as an Sc test — the implementation §3.2a forbids — converts these and fails here."
|
|
2086
|
+
},
|
|
2087
|
+
{
|
|
2088
|
+
"id": "en-us-yaml-plain-value",
|
|
2089
|
+
"rule": "quotes",
|
|
2090
|
+
"mode": "yaml",
|
|
2091
|
+
"keys": [
|
|
2092
|
+
"description"
|
|
2093
|
+
],
|
|
2094
|
+
"in": "description: He said \"hi\" to us\n",
|
|
2095
|
+
"out": "description: He said “hi” to us\n",
|
|
2096
|
+
"note": "modes.md §3.8.4: a plain scalar under a listed key is a processable span and converts exactly as text mode does."
|
|
2097
|
+
},
|
|
2098
|
+
{
|
|
2099
|
+
"id": "en-us-yaml-unlisted-key-untouched",
|
|
2100
|
+
"rule": "ellipsis",
|
|
2101
|
+
"mode": "yaml",
|
|
2102
|
+
"keys": [
|
|
2103
|
+
"description"
|
|
2104
|
+
],
|
|
2105
|
+
"in": "description: one...two\nrun: three...four\n",
|
|
2106
|
+
"out": "description: one…two\nrun: three...four\n",
|
|
2107
|
+
"note": "modes.md §3.8.2: `keys` is the whole of what makes a scalar processable. A port that processes every string scalar changes the `run:` value too, which is the defect this option exists to prevent."
|
|
2108
|
+
},
|
|
2109
|
+
{
|
|
2110
|
+
"id": "en-us-yaml-empty-keys-untouched",
|
|
2111
|
+
"rule": "ellipsis",
|
|
2112
|
+
"mode": "yaml",
|
|
2113
|
+
"keys": [],
|
|
2114
|
+
"in": "description: one...two\n",
|
|
2115
|
+
"out": "description: one...two\n",
|
|
2116
|
+
"note": "modes.md §3.8.2: an empty `keys` list is legal and yields no spans — \"process nothing\" is a choice a caller may make, not an error."
|
|
2117
|
+
},
|
|
2118
|
+
{
|
|
2119
|
+
"id": "en-us-yaml-key-never-processed",
|
|
2120
|
+
"rule": "ellipsis",
|
|
2121
|
+
"mode": "yaml",
|
|
2122
|
+
"keys": [
|
|
2123
|
+
"a...b"
|
|
2124
|
+
],
|
|
2125
|
+
"in": "a...b: one...two\n",
|
|
2126
|
+
"out": "a...b: one…two\n",
|
|
2127
|
+
"note": "modes.md §3.8.4 step 5: keys are never processable, including the key that was matched against `keys`."
|
|
2128
|
+
},
|
|
2129
|
+
{
|
|
2130
|
+
"id": "en-us-yaml-colon-inside-key",
|
|
2131
|
+
"rule": "ellipsis",
|
|
2132
|
+
"mode": "yaml",
|
|
2133
|
+
"keys": [
|
|
2134
|
+
"a:b"
|
|
2135
|
+
],
|
|
2136
|
+
"in": "a:b: one...two\n",
|
|
2137
|
+
"out": "a:b: one…two\n",
|
|
2138
|
+
"note": "modes.md §3.8.4 step 5: a colon not followed by U+0020 or the line end is an ordinary key character, so the key here is `a:b`. A port that stops at the first colon finds no key and yields no spans."
|
|
2139
|
+
},
|
|
2140
|
+
{
|
|
2141
|
+
"id": "en-us-yaml-quoted-scalar-with-colon",
|
|
2142
|
+
"rule": "ellipsis",
|
|
2143
|
+
"mode": "yaml",
|
|
2144
|
+
"keys": [
|
|
2145
|
+
"title"
|
|
2146
|
+
],
|
|
2147
|
+
"in": "title: \"Chapter 1: one...two\"\n",
|
|
2148
|
+
"out": "title: \"Chapter 1: one…two\"\n",
|
|
2149
|
+
"note": "modes.md §3.8.6: the plain-scalar colon test does not apply to a quoted scalar — quoting neutralises the colon. A port that applies it declines this line."
|
|
2150
|
+
},
|
|
2151
|
+
{
|
|
2152
|
+
"id": "en-us-yaml-block-literal-lines",
|
|
2153
|
+
"rule": "ellipsis",
|
|
2154
|
+
"mode": "yaml",
|
|
2155
|
+
"keys": [
|
|
2156
|
+
"description"
|
|
2157
|
+
],
|
|
2158
|
+
"in": "description: |\n one...two\n three...four\n",
|
|
2159
|
+
"out": "description: |\n one…two\n three…four\n",
|
|
2160
|
+
"note": "modes.md §3.8.5: one span per content line, beginning after the block indentation; indentation beyond that is content and stays inside the span."
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
"id": "en-us-yaml-chomping-clip",
|
|
2164
|
+
"rule": "ellipsis",
|
|
2165
|
+
"mode": "yaml",
|
|
2166
|
+
"keys": [
|
|
2167
|
+
"description"
|
|
2168
|
+
],
|
|
2169
|
+
"in": "description: |\n one...two\n\n\nz: 1\n",
|
|
2170
|
+
"out": "description: |\n one…two\n\n\nz: 1\n",
|
|
2171
|
+
"note": "modes.md §3.8.5: the trailing line terminators the chomping indicator governs are outside every span. Compare en-us-yaml-chomping-strip and en-us-yaml-chomping-keep: three indicators, identical content edit, identical trailing bytes."
|
|
2172
|
+
},
|
|
2173
|
+
{
|
|
2174
|
+
"id": "en-us-yaml-chomping-strip",
|
|
2175
|
+
"rule": "ellipsis",
|
|
2176
|
+
"mode": "yaml",
|
|
2177
|
+
"keys": [
|
|
2178
|
+
"description"
|
|
2179
|
+
],
|
|
2180
|
+
"in": "description: |-\n one...two\n\n\nz: 1\n",
|
|
2181
|
+
"out": "description: |-\n one…two\n\n\nz: 1\n",
|
|
2182
|
+
"note": "modes.md §3.8.5: `|-` differs from `|` only in bytes the mode never touches. A port that decodes the block and re-encodes it produces a different byte count here than for en-us-yaml-chomping-clip."
|
|
2183
|
+
},
|
|
2184
|
+
{
|
|
2185
|
+
"id": "en-us-yaml-chomping-keep",
|
|
2186
|
+
"rule": "ellipsis",
|
|
2187
|
+
"mode": "yaml",
|
|
2188
|
+
"keys": [
|
|
2189
|
+
"description"
|
|
2190
|
+
],
|
|
2191
|
+
"in": "description: |+\n one...two\n\n\nz: 1\n",
|
|
2192
|
+
"out": "description: |+\n one…two\n\n\nz: 1\n",
|
|
2193
|
+
"note": "modes.md §3.8.5: `|+` keeps every trailing line terminator, and they are outside every span. This is the case the reported corruption in §3.8.1 failed."
|
|
2194
|
+
},
|
|
2195
|
+
{
|
|
2196
|
+
"id": "en-us-yaml-quotes-pair-across-block-lines",
|
|
2197
|
+
"rule": "quotes",
|
|
2198
|
+
"mode": "yaml",
|
|
2199
|
+
"keys": [
|
|
2200
|
+
"description"
|
|
2201
|
+
],
|
|
2202
|
+
"in": "description: |\n He said \"hi\n there\" and left\n",
|
|
2203
|
+
"out": "description: |\n He said “hi\n there” and left\n",
|
|
2204
|
+
"note": "modes.md §3.2 model C: a block scalar's content lines are separate spans joined by a −2 marker, so a quotation opened on one line pairs with a mark on the next. A port that runs each line independently leaves both marks straight."
|
|
2205
|
+
},
|
|
2206
|
+
{
|
|
2207
|
+
"id": "en-us-yaml-multiline-quoted-untouched",
|
|
2208
|
+
"rule": "quotes",
|
|
2209
|
+
"mode": "yaml",
|
|
2210
|
+
"keys": [
|
|
2211
|
+
"a",
|
|
2212
|
+
"b"
|
|
2213
|
+
],
|
|
2214
|
+
"in": "a: \"open here\n b: some prose \"word\" close\"\n",
|
|
2215
|
+
"out": "a: \"open here\n b: some prose \"word\" close\"\n",
|
|
2216
|
+
"note": "modes.md §3.8.4 step 7: a quoted scalar that does not close on its opening line consumes its continuation lines, which are never rescanned. A port that rescans them puts the scalar's own closing quote inside a span, and `quotes` can then leave the scalar unterminated."
|
|
2217
|
+
},
|
|
2218
|
+
{
|
|
2219
|
+
"id": "en-us-yaml-multiline-flow-untouched",
|
|
2220
|
+
"rule": "ellipsis",
|
|
2221
|
+
"mode": "yaml",
|
|
2222
|
+
"keys": [
|
|
2223
|
+
"a",
|
|
2224
|
+
"b",
|
|
2225
|
+
"c"
|
|
2226
|
+
],
|
|
2227
|
+
"in": "a: {\n b: one...two,\n c: x\n}\n",
|
|
2228
|
+
"out": "a: {\n b: one...two,\n c: x\n}\n",
|
|
2229
|
+
"note": "modes.md §3.8.4 step 7: a flow collection spanning several lines consumes them all. A port that bails only on the opening line processes the interior and can edit next to the structural comma."
|
|
2230
|
+
},
|
|
2231
|
+
{
|
|
2232
|
+
"id": "en-us-yaml-block-ambiguous-indent-untouched",
|
|
2233
|
+
"rule": "ellipsis",
|
|
2234
|
+
"mode": "yaml",
|
|
2235
|
+
"keys": [
|
|
2236
|
+
"description"
|
|
2237
|
+
],
|
|
2238
|
+
"in": "description: |\n deep one...two\n shallow three...four\n",
|
|
2239
|
+
"out": "description: |\n deep one...two\n shallow three...four\n",
|
|
2240
|
+
"note": "modes.md §3.8.5: a later content line dedented inside the block is ambiguous, so the whole block yields no spans rather than the scan guessing which line the author meant as content."
|
|
2241
|
+
},
|
|
2242
|
+
{
|
|
2243
|
+
"id": "en-us-yaml-not-yaml-untouched",
|
|
2244
|
+
"rule": "ellipsis",
|
|
2245
|
+
"mode": "yaml",
|
|
2246
|
+
"keys": [
|
|
2247
|
+
"description"
|
|
2248
|
+
],
|
|
2249
|
+
"in": "{{ not yaml at all ... }}\n\t\tmixed\tindentation...\n",
|
|
2250
|
+
"out": "{{ not yaml at all ... }}\n\t\tmixed\tindentation...\n",
|
|
2251
|
+
"note": "modes.md §3.8.3: a construct the scan does not recognise yields no spans and the input comes back byte for byte. `transform` never throws on input in this mode."
|
|
2252
|
+
},
|
|
2253
|
+
{
|
|
2254
|
+
"id": "en-us-yaml-document-marker-prefix-untouched",
|
|
2255
|
+
"rule": "ellipsis",
|
|
2256
|
+
"mode": "yaml",
|
|
2257
|
+
"keys": [
|
|
2258
|
+
"description",
|
|
2259
|
+
"--- description"
|
|
2260
|
+
],
|
|
2261
|
+
"in": "--- description: one...two\n",
|
|
2262
|
+
"out": "--- description: one...two\n",
|
|
2263
|
+
"note": "modes.md §3.8.4 step 3: a document marker introducing a node is declined along with the bare form, so no key of `--- description` can ever be formed."
|
|
2264
|
+
},
|
|
2265
|
+
{
|
|
2266
|
+
"id": "en-us-yaml-astral-preserved",
|
|
2267
|
+
"rule": "quotes",
|
|
2268
|
+
"mode": "yaml",
|
|
2269
|
+
"keys": [
|
|
2270
|
+
"description"
|
|
2271
|
+
],
|
|
2272
|
+
"in": "description: A rocket 🚀 and a \"quote\"\n",
|
|
2273
|
+
"out": "description: A rocket 🚀 and a “quote”\n",
|
|
2274
|
+
"note": "modes.md §4: offsets are code points, not code units. A runtime indexing UTF-16 code units mis-slices the span after the astral character."
|
|
2275
|
+
},
|
|
2276
|
+
{
|
|
2277
|
+
"id": "en-us-modes-three-dash-span-edge-html",
|
|
2278
|
+
"rule": "dashes",
|
|
2279
|
+
"mode": "html",
|
|
2280
|
+
"in": "a<em>---</em>b",
|
|
2281
|
+
"out": "a<em>—</em>b",
|
|
2282
|
+
"note": "modes.md §3.4: an em-tight locale emits no U+0020, so the character clause does not fire and the edit applies at the extremity. The clause tests the character, not the length — this is the case that shows why."
|
|
2283
|
+
},
|
|
2284
|
+
{
|
|
2285
|
+
"id": "en-us-yaml-folded-clip",
|
|
2286
|
+
"rule": "ellipsis",
|
|
2287
|
+
"mode": "yaml",
|
|
2288
|
+
"keys": [
|
|
2289
|
+
"description"
|
|
2290
|
+
],
|
|
2291
|
+
"in": "description: >\n one...two\n\n\nz: 1\n",
|
|
2292
|
+
"out": "description: >\n one…two\n\n\nz: 1\n",
|
|
2293
|
+
"note": "modes.md §3.8.5: `>` is handled identically to `|` because the difference between them lives entirely in bytes the mode never touches. Companion to en-us-yaml-folded-strip and en-us-yaml-folded-keep."
|
|
2294
|
+
},
|
|
2295
|
+
{
|
|
2296
|
+
"id": "en-us-yaml-folded-strip",
|
|
2297
|
+
"rule": "ellipsis",
|
|
2298
|
+
"mode": "yaml",
|
|
2299
|
+
"keys": [
|
|
2300
|
+
"description"
|
|
2301
|
+
],
|
|
2302
|
+
"in": "description: >-\n one...two\n\n\nz: 1\n",
|
|
2303
|
+
"out": "description: >-\n one…two\n\n\nz: 1\n",
|
|
2304
|
+
"note": "modes.md §3.8.5: identical content edit and identical trailing bytes to en-us-yaml-folded-clip and en-us-yaml-folded-keep — a port that decodes the block and re-encodes it produces three different byte counts."
|
|
2305
|
+
},
|
|
2306
|
+
{
|
|
2307
|
+
"id": "en-us-yaml-folded-keep",
|
|
2308
|
+
"rule": "ellipsis",
|
|
2309
|
+
"mode": "yaml",
|
|
2310
|
+
"keys": [
|
|
2311
|
+
"description"
|
|
2312
|
+
],
|
|
2313
|
+
"in": "description: >+\n one...two\n\n\nz: 1\n",
|
|
2314
|
+
"out": "description: >+\n one…two\n\n\nz: 1\n",
|
|
2315
|
+
"note": "modes.md §3.8.5: `>+` keeps every trailing line terminator, and they lie outside every span. Completes the six chomping indicators with en-us-yaml-chomping-clip, -strip and -keep."
|
|
2316
|
+
},
|
|
2317
|
+
{
|
|
2318
|
+
"id": "en-us-yaml-quoted-key-untouched",
|
|
2319
|
+
"rule": "ellipsis",
|
|
2320
|
+
"mode": "yaml",
|
|
2321
|
+
"keys": [
|
|
2322
|
+
"description"
|
|
2323
|
+
],
|
|
2324
|
+
"in": "\"description\": one...two\n",
|
|
2325
|
+
"out": "\"description\": one...two\n",
|
|
2326
|
+
"note": "modes.md §3.8.4 step 5 and §7.11: a key containing a quote is declined before it is ever compared against `keys`, so a document that quotes its keys gets nothing from this mode. An accepted cost, pinned so it is a decision rather than a surprise."
|
|
2327
|
+
},
|
|
2328
|
+
{
|
|
2329
|
+
"id": "en-us-yaml-bang-in-key-untouched",
|
|
2330
|
+
"rule": "ellipsis",
|
|
2331
|
+
"mode": "yaml",
|
|
2332
|
+
"keys": [
|
|
2333
|
+
"a!b"
|
|
2334
|
+
],
|
|
2335
|
+
"in": "a!b: one...two\n",
|
|
2336
|
+
"out": "a!b: one...two\n",
|
|
2337
|
+
"note": "modes.md §3.8.4 step 5: the character test applies at every position of the key, not only the first, so a key merely containing `!` is declined too. A port testing only the first position processes this line and diverges."
|
|
2338
|
+
},
|
|
2339
|
+
{
|
|
2340
|
+
"id": "en-us-yaml-same-key-two-depths",
|
|
2341
|
+
"rule": "ellipsis",
|
|
2342
|
+
"mode": "yaml",
|
|
2343
|
+
"keys": [
|
|
2344
|
+
"description"
|
|
2345
|
+
],
|
|
2346
|
+
"in": "description: one...two\nnested:\n inner:\n description: three...four\n",
|
|
2347
|
+
"out": "description: one…two\nnested:\n inner:\n description: three…four\n",
|
|
2348
|
+
"note": "modes.md §3.8.2: `keys` matches a bare name at any depth and nothing narrower. Both occurrences convert; a port that matches only at the top level converts one."
|
|
2349
|
+
},
|
|
2350
|
+
{
|
|
2351
|
+
"id": "en-us-yaml-crlf-block",
|
|
2352
|
+
"rule": "ellipsis",
|
|
2353
|
+
"mode": "yaml",
|
|
2354
|
+
"keys": [
|
|
2355
|
+
"description"
|
|
2356
|
+
],
|
|
2357
|
+
"in": "description: |\r\n one...two\r\n",
|
|
2358
|
+
"out": "description: |\r\n one…two\r\n",
|
|
2359
|
+
"note": "modes.md §3.8.4: a U+000D immediately before the U+000A is a terminator, not part of the line, so a CRLF file yields the same spans as the same bytes with LF and the carriage returns come back untouched. A port splitting lines on U+000A alone reads the header as `|` + U+000D and yields nothing."
|
|
2360
|
+
},
|
|
2361
|
+
{
|
|
2362
|
+
"id": "en-us-yaml-sequence-entry",
|
|
2363
|
+
"rule": "ellipsis",
|
|
2364
|
+
"mode": "yaml",
|
|
2365
|
+
"keys": [
|
|
2366
|
+
"description"
|
|
2367
|
+
],
|
|
2368
|
+
"in": "- description: one...two\n- - description: three...four\n",
|
|
2369
|
+
"out": "- description: one…two\n- - description: three…four\n",
|
|
2370
|
+
"note": "modes.md §3.8.4 step 4: block sequence entries are consumed rather than skipped, and they nest."
|
|
2371
|
+
},
|
|
2372
|
+
{
|
|
2373
|
+
"id": "en-us-yaml-single-quoted",
|
|
2374
|
+
"rule": "ellipsis",
|
|
2375
|
+
"mode": "yaml",
|
|
2376
|
+
"keys": [
|
|
2377
|
+
"description"
|
|
2378
|
+
],
|
|
2379
|
+
"in": "description: 'one...two'\n",
|
|
2380
|
+
"out": "description: 'one…two'\n",
|
|
2381
|
+
"note": "modes.md §3.8.6: a single-quoted scalar's content is one span; the quotes themselves are outside it."
|
|
2382
|
+
},
|
|
2383
|
+
{
|
|
2384
|
+
"id": "en-us-yaml-single-quoted-escape-untouched",
|
|
2385
|
+
"rule": "ellipsis",
|
|
2386
|
+
"mode": "yaml",
|
|
2387
|
+
"keys": [
|
|
2388
|
+
"description"
|
|
2389
|
+
],
|
|
2390
|
+
"in": "description: 'it''s one...two'\n",
|
|
2391
|
+
"out": "description: 'it''s one...two'\n",
|
|
2392
|
+
"note": "modes.md §3.8.6: `''` makes the source spell the content with more characters than it has, so the offset model of §3.1 cannot hold and the scalar yields no spans."
|
|
2393
|
+
},
|
|
2394
|
+
{
|
|
2395
|
+
"id": "en-us-yaml-double-quoted-escape-untouched",
|
|
2396
|
+
"rule": "ellipsis",
|
|
2397
|
+
"mode": "yaml",
|
|
2398
|
+
"keys": [
|
|
2399
|
+
"description"
|
|
2400
|
+
],
|
|
2401
|
+
"in": "description: \"one \\\"two\\\"... three\"\n",
|
|
2402
|
+
"out": "description: \"one \\\"two\\\"... three\"\n",
|
|
2403
|
+
"note": "modes.md §3.8.6: a backslash in a double-quoted scalar means the same thing — source characters and content characters stop being the same, exactly as an HTML character reference does in §3.6."
|
|
2404
|
+
},
|
|
2405
|
+
{
|
|
2406
|
+
"id": "en-us-yaml-anchor-untouched",
|
|
2407
|
+
"rule": "ellipsis",
|
|
2408
|
+
"mode": "yaml",
|
|
2409
|
+
"keys": [
|
|
2410
|
+
"description",
|
|
2411
|
+
"use"
|
|
2412
|
+
],
|
|
2413
|
+
"in": "description: &anchor one...two\nuse: *anchor\n",
|
|
2414
|
+
"out": "description: &anchor one...two\nuse: *anchor\n",
|
|
2415
|
+
"note": "modes.md §3.8.4 step 9: an anchored or aliased value is not a construct this scan claims, listed key or not."
|
|
2416
|
+
},
|
|
2417
|
+
{
|
|
2418
|
+
"id": "en-us-yaml-tag-untouched",
|
|
2419
|
+
"rule": "ellipsis",
|
|
2420
|
+
"mode": "yaml",
|
|
2421
|
+
"keys": [
|
|
2422
|
+
"description"
|
|
2423
|
+
],
|
|
2424
|
+
"in": "description: !!str one...two\n",
|
|
2425
|
+
"out": "description: !!str one...two\n",
|
|
2426
|
+
"note": "modes.md §3.8.4 step 9: a tagged value is declined for the same reason as an anchored one."
|
|
2427
|
+
},
|
|
2428
|
+
{
|
|
2429
|
+
"id": "en-us-yaml-comment-only-value",
|
|
2430
|
+
"rule": "ellipsis",
|
|
2431
|
+
"mode": "yaml",
|
|
2432
|
+
"keys": [
|
|
2433
|
+
"description"
|
|
2434
|
+
],
|
|
2435
|
+
"in": "# a comment...here\n%TAG ! tag:example.com,2000:\ndescription: # one...two\n",
|
|
2436
|
+
"out": "# a comment...here\n%TAG ! tag:example.com,2000:\ndescription: # one...two\n",
|
|
2437
|
+
"note": "modes.md §3.8.4 steps 2 and 9: a comment line, a directive line, and a value that is only a comment all yield no spans."
|
|
2438
|
+
},
|
|
2439
|
+
{
|
|
2440
|
+
"id": "en-us-yaml-document-markers",
|
|
2441
|
+
"rule": "ellipsis",
|
|
2442
|
+
"mode": "yaml",
|
|
2443
|
+
"keys": [
|
|
2444
|
+
"description"
|
|
2445
|
+
],
|
|
2446
|
+
"in": "---\ndescription: one...two\n...\n",
|
|
2447
|
+
"out": "---\ndescription: one…two\n...\n",
|
|
2448
|
+
"note": "modes.md §3.8.4 step 3: the bare document markers are declined as lines, and the mapping between them is scanned normally."
|
|
2449
|
+
},
|
|
2450
|
+
{
|
|
2451
|
+
"id": "en-us-yaml-flow-one-line-untouched",
|
|
2452
|
+
"rule": "ellipsis",
|
|
2453
|
+
"mode": "yaml",
|
|
2454
|
+
"keys": [
|
|
2455
|
+
"description",
|
|
2456
|
+
"inner"
|
|
2457
|
+
],
|
|
2458
|
+
"in": "description: [one...two, three]\ninner: {a: four...five}\n",
|
|
2459
|
+
"out": "description: [one...two, three]\ninner: {a: four...five}\n",
|
|
2460
|
+
"note": "modes.md §3.8.4 step 9: a flow collection is declined whole, on one line as much as across several."
|
|
2461
|
+
},
|
|
2462
|
+
{
|
|
2463
|
+
"id": "en-us-yaml-explicit-indent-indicator",
|
|
2464
|
+
"rule": "ellipsis",
|
|
2465
|
+
"mode": "yaml",
|
|
2466
|
+
"keys": [
|
|
2467
|
+
"description"
|
|
2468
|
+
],
|
|
2469
|
+
"in": "description: |2\n one...two\n",
|
|
2470
|
+
"out": "description: |2\n one…two\n",
|
|
2471
|
+
"note": "modes.md §3.8.5: an explicit indentation indicator sets `bi` to `indent + n`, so the leading space here is content and stays inside the span."
|
|
2472
|
+
},
|
|
2473
|
+
{
|
|
2474
|
+
"id": "en-us-yaml-empty-value-nested-node",
|
|
2475
|
+
"rule": "ellipsis",
|
|
2476
|
+
"mode": "yaml",
|
|
2477
|
+
"keys": [
|
|
2478
|
+
"description"
|
|
2479
|
+
],
|
|
2480
|
+
"in": "outer:\n description: one...two\n",
|
|
2481
|
+
"out": "outer:\n description: one…two\n",
|
|
2482
|
+
"note": "modes.md §3.8.4 step 6: a key with no inline value introduces a nested node whose lines ARE scanned on their own — the one case where following lines are not consumed by step 7."
|
|
2483
|
+
},
|
|
2484
|
+
{
|
|
2485
|
+
"id": "en-us-yaml-multiline-plain-untouched",
|
|
2486
|
+
"rule": "ellipsis",
|
|
2487
|
+
"mode": "yaml",
|
|
2488
|
+
"keys": [
|
|
2489
|
+
"description"
|
|
2490
|
+
],
|
|
2491
|
+
"in": "description: one...two\n three...four\n",
|
|
2492
|
+
"out": "description: one...two\n three...four\n",
|
|
2493
|
+
"note": "modes.md §3.8.6: a multi-line plain scalar's folding is a construct this scan does not claim, so the whole value yields no spans — including its first line."
|
|
1869
2494
|
}
|
|
1870
2495
|
]
|
|
1871
2496
|
}
|