@spintax/core 0.1.5 → 0.1.6
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.
- package/CHANGELOG.md +38 -0
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,44 @@
|
|
|
3
3
|
All notable changes to `@spintax/core` are documented here. This project adheres to
|
|
4
4
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
5
5
|
|
|
6
|
+
## 0.1.6 — 2026-07-13
|
|
7
|
+
|
|
8
|
+
Two post-process fixes. **Supersedes 0.1.5** — upgrade straight past it. No API change.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **A run of sentence punctuation is no longer split from the inside.** This is not a Spanish issue
|
|
13
|
+
and it predates the 0.1.5 work: the "space after `.!?`" rule looked exactly one character ahead
|
|
14
|
+
and never at the rest of the run, so it fired *between* the marks.
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
wait... what? → Wait. . . What? (0.1.5 and earlier)
|
|
18
|
+
wow!!! → Wow! ! !
|
|
19
|
+
really?! → Really? !
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The ASCII ellipsis is the common casualty — and the Unicode `…` is *not* in the `[.!?]` class,
|
|
23
|
+
which is exactly why the corpus's existing ellipsis fixture never caught it. A run is now matched
|
|
24
|
+
whole and required to be complete: `([.!?]+)(?![.!?])`. The guard is load-bearing — a greedy `+`
|
|
25
|
+
alone gives ground back *into* the run to satisfy the lookaheads and yields `Wow!! !`.
|
|
26
|
+
|
|
27
|
+
- **`¡¿Qué haces?!` keeps its capital.** The 0.1.5 opener rule allowed exactly *one* opener, so the
|
|
28
|
+
RAE form for a sentence that is both a question and an exclamation — the most Spanish sentence
|
|
29
|
+
there is — still lost its capital. An opener followed by markup (`¿<strong>cómo</strong> estás?`,
|
|
30
|
+
`<p>¿<a href="/ayuda">necesitas ayuda</a>?</p>`) failed for the same reason: the old lead only
|
|
31
|
+
allowed `tags → opener → letter`, never `opener → tags → letter`.
|
|
32
|
+
|
|
33
|
+
The lead is now any run of tags, sentence openers and whitespace, in any order. The opener set
|
|
34
|
+
stays deliberately **narrow** — quotes and brackets are still not openers, and the fixtures added
|
|
35
|
+
in 0.1.5 keep guarding that.
|
|
36
|
+
|
|
37
|
+
### Notes
|
|
38
|
+
|
|
39
|
+
- Mirrored into the PHP plugin engine (released there as 2.3.3). Verified against the shared golden
|
|
40
|
+
corpus in both engines: TS 243 tests; the conformance runner against the real plugin engine 107
|
|
41
|
+
tests / 120 assertions. No performance regression — the pathological-input cost is unchanged from
|
|
42
|
+
0.1.5 and comes from the URL/domain shields, not from these rules.
|
|
43
|
+
|
|
6
44
|
## 0.1.5 — 2026-07-13
|
|
7
45
|
|
|
8
46
|
Spanish post-process fix. No API change.
|
package/dist/index.cjs
CHANGED
|
@@ -914,18 +914,18 @@ var MULTI_ABBR_RE = new RegExp(`\\b(?:\\p{L}{1,2}\\.${S}*){2,}`, "gu");
|
|
|
914
914
|
var SINGLE_ABBR_RE = new RegExp(`(?<![\\p{L}\\p{N}])(?:${SINGLE_ABBREVS.join("|")})\\.(?=${S}|$|<)`, "giu");
|
|
915
915
|
var TRAILING_PUNCT_RE = /([.,;:!]+)$/u;
|
|
916
916
|
var SENTENCE_OPENERS = "\xBF\xA1";
|
|
917
|
-
var
|
|
917
|
+
var LEAD = `(?:<[^>]+>|[${SENTENCE_OPENERS}]|${S})*`;
|
|
918
918
|
var SPACE_BEFORE_PUNCT_RE = new RegExp(`${S}+([,;:!?.])`, "gu");
|
|
919
919
|
var SPACE_AFTER_COMMA_RE = new RegExp(`([,;:])(?!\\d)(?!${S}|$|<)`, "gu");
|
|
920
|
-
var SPACE_AFTER_SENTENCE_RE = new RegExp(`([.!?])(?!\\d)(?!${S}|$|<)`, "gu");
|
|
920
|
+
var SPACE_AFTER_SENTENCE_RE = new RegExp(`([.!?]+)(?![.!?])(?!\\d)(?!${S}|$|<)`, "gu");
|
|
921
921
|
var SPACE_AFTER_OPENER_RE = new RegExp(`([${SENTENCE_OPENERS}])${S}+`, "gu");
|
|
922
|
-
var CAP_FIRST_RE = new RegExp(`^(${
|
|
923
|
-
var CAP_AFTER_SENTENCE_RE = new RegExp(`([.!?\u2026])(${
|
|
922
|
+
var CAP_FIRST_RE = new RegExp(`^(${LEAD})(\\p{Ll})`, "u");
|
|
923
|
+
var CAP_AFTER_SENTENCE_RE = new RegExp(`([.!?\u2026])(${LEAD})(\\p{Ll})`, "gu");
|
|
924
924
|
var CAP_AFTER_BLOCK_RE = new RegExp(
|
|
925
|
-
`(<\\/?(?:p|h[1-6]|li|blockquote|div|td|th)[^>]*>${
|
|
925
|
+
`(<\\/?(?:p|h[1-6]|li|blockquote|div|td|th)[^>]*>${LEAD})(\\p{Ll})`,
|
|
926
926
|
"giu"
|
|
927
927
|
);
|
|
928
|
-
var CAP_AFTER_BREAK_RE = new RegExp(`(\\n${
|
|
928
|
+
var CAP_AFTER_BREAK_RE = new RegExp(`(\\n${LEAD})(\\p{Ll})`, "gu");
|
|
929
929
|
var up = (ch) => ch.toUpperCase();
|
|
930
930
|
function postProcess(input) {
|
|
931
931
|
const placeholders = /* @__PURE__ */ new Map();
|