@descent-vtt/spec-graph 0.18.0 → 0.20.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.
- package/CHANGELOG.md +126 -0
- package/README.md +39 -6
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +62 -19
- package/dist/cli.js.map +1 -1
- package/dist/extract.js +56 -12
- package/dist/extract.js.map +1 -1
- package/dist/glob.d.ts +5 -0
- package/dist/glob.js +6 -1
- package/dist/glob.js.map +1 -1
- package/dist/paths.d.ts +24 -0
- package/dist/paths.js +31 -0
- package/dist/paths.js.map +1 -1
- package/package.json +1 -1
package/dist/extract.js
CHANGED
|
@@ -351,13 +351,39 @@ const NEGATION = /(?:^|[^\p{L}\p{N}-])(?:no|not|no-one|nobody|none|never|neither
|
|
|
351
351
|
* by" are read, and "not only blocked by" and "nothing but blocked by",
|
|
352
352
|
* which state the relation, are not. Only a space stands between, so a
|
|
353
353
|
* mark keeps the word to itself: the option `"never" blocked by` states the
|
|
354
|
-
* relation, as "Not in this release: deferred to" does. A comma
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
354
|
+
* relation, as "Not in this release: deferred to" does. A comma does too,
|
|
355
|
+
* and ends the clause the word belongs to: "If not, blocked by" and "both
|
|
356
|
+
* or neither, because" state the relation, where with the comma blanked
|
|
357
|
+
* they were cancelled (ADR-0006, 2026-10-19). A contraction is a negation,
|
|
358
|
+
* `isn't` and `doesn’t`, and so is `cannot`. Tested against the text just
|
|
359
|
+
* before the phrase, which ends with the space or the comma before it.
|
|
360
|
+
*
|
|
361
|
+
* An aside between the two, closed by a comma of its own, leaves the clause
|
|
362
|
+
* open: "Not, as it happens, blocked by", "never, ever, blocked by" and "it
|
|
363
|
+
* is not, as far as anyone knows, blocked by" deny the relation as the words
|
|
364
|
+
* without the aside do. The aside is anything up to a comma, and may hold
|
|
365
|
+
* several, so the negation may also end a clause the phrase is not in -
|
|
366
|
+
* "if not, then, blocked by" - and the relation such a sentence states is
|
|
367
|
+
* missed, which ADR-0006 prefers to one it denies (2026-10-24). The same few
|
|
368
|
+
* words may stand after the last comma, "not, in the end, been superseded
|
|
369
|
+
* by". A run of spaces and commas is one comma in the text this is tested
|
|
370
|
+
* on, so no aside is empty and `.*` would read as `.+` does; and only
|
|
371
|
+
* whether the pattern matches is asked, so a lazy `.+?` reads alike too.
|
|
372
|
+
*/
|
|
373
|
+
const NEGATED_BEFORE = /(?:^|[^\p{L}\p{N}-])(?:no|not|no one|no-one|nobody|none|never|neither|nor|nothing|without|cannot|\p{L}+n['’]t)(?: (?:be|been|being|is|are|was|were|yet|longer|ever|even|currently|actually|really|necessarily|always))*(?: |,.+,(?:(?:be|been|being|is|are|was|were|yet|longer|ever|even|currently|actually|really|necessarily|always) )*)$/u;
|
|
374
|
+
/**
|
|
375
|
+
* A word that points the reader at the reference, and governs it as a
|
|
376
|
+
* citation from nearer than any phrase before it: "Per tick, see [ADR-7]"
|
|
377
|
+
* read ADR-7 as a premise, and "blocked by the cache, see [ADR-7]" read it
|
|
378
|
+
* as what blocks. `see` is no phrase for the vagueness that makes it a
|
|
379
|
+
* citation, and between a phrase and the reference it says the reference is
|
|
380
|
+
* where to read more, not what the phrase names (ADR-0006, 2026-10-24). It
|
|
381
|
+
* is a word as a negation is, between anything but a letter, a digit or a
|
|
382
|
+
* hyphen, so "the must-see list", "the licensee" and "seen in" point at
|
|
383
|
+
* nothing. The text it is tested on starts just after a phrase, where no
|
|
384
|
+
* letter stands, so the word is never its first and needs no start of text.
|
|
359
385
|
*/
|
|
360
|
-
const
|
|
386
|
+
const POINTER = /[^\p{L}\p{N}-]see(?![\p{L}\p{N}-])/u;
|
|
361
387
|
/**
|
|
362
388
|
* A code span that holds nothing but a negation word: `` `none` ``.
|
|
363
389
|
*
|
|
@@ -1276,7 +1302,7 @@ function ownerOf(items, offset) {
|
|
|
1276
1302
|
* neutral citation.
|
|
1277
1303
|
*/
|
|
1278
1304
|
export function classifyReference(text, start, end, section) {
|
|
1279
|
-
const before = sentenceBefore(text, start);
|
|
1305
|
+
const { words: before, commas } = sentenceBefore(text, start);
|
|
1280
1306
|
// Left to right, so the last match within the window is the nearest one - and
|
|
1281
1307
|
// the nearest governing phrase is the one that governs. `matchAll`, not a
|
|
1282
1308
|
// loop over `exec`: an empty match leaves `lastIndex` where it began, and
|
|
@@ -1292,11 +1318,20 @@ export function classifyReference(text, start, end, section) {
|
|
|
1292
1318
|
continue;
|
|
1293
1319
|
// What sits between the phrase and the reference has to be connective. A
|
|
1294
1320
|
// negation in there reverses the claim the phrase would otherwise make,
|
|
1295
|
-
// and so does one just before the phrase
|
|
1321
|
+
// and so does one just before the phrase, where no comma ends its clause
|
|
1322
|
+
// first. A pointer in there governs the reference itself, as a citation.
|
|
1296
1323
|
if (NEGATION.test(before.slice(end)))
|
|
1297
1324
|
continue;
|
|
1298
|
-
if (
|
|
1325
|
+
if (POINTER.test(before.slice(end)))
|
|
1326
|
+
continue;
|
|
1327
|
+
// A negation before a phrase stands between any phrase before it and the
|
|
1328
|
+
// reference, and denies what follows it: a phrase it leaves before an
|
|
1329
|
+
// aside governs no more than the one it cancels, so "Not, as decided in
|
|
1330
|
+
// [ADR-3], blocked by [ADR-7]" makes ADR-7 a premise of nothing.
|
|
1331
|
+
if (NEGATED_BEFORE.test(commas.slice(0, m.index))) {
|
|
1332
|
+
best = null;
|
|
1299
1333
|
continue;
|
|
1334
|
+
}
|
|
1300
1335
|
// Always found: the pattern was compiled from this table's own keys, and a
|
|
1301
1336
|
// lower-cased search matches them only as written. The check is for types.
|
|
1302
1337
|
const rule = VERB_LOOKUP.get(phrase);
|
|
@@ -1358,17 +1393,26 @@ const STATEMENT_BREAK = /[.?!;]\s|[。?!;]|\n\s*\n|\n\s*[-*+>#]|\|/g;
|
|
|
1358
1393
|
* names a word, and `isn't` is one word. Kept, each counts toward the
|
|
1359
1394
|
* distance a phrase reaches where it stands beside a space, as a curly one
|
|
1360
1395
|
* did (ADR-0006, 2026-10-18).
|
|
1396
|
+
*
|
|
1397
|
+
* The same text is given a second time with each run of spaces that held a
|
|
1398
|
+
* comma written as the comma: one character either way, so the two line up
|
|
1399
|
+
* and a comma counts toward no phrase's reach, and a negation before a
|
|
1400
|
+
* phrase is read from the second, where a comma keeps the two apart
|
|
1401
|
+
* (ADR-0006, 2026-10-19).
|
|
1361
1402
|
*/
|
|
1362
1403
|
function sentenceBefore(text, start) {
|
|
1363
1404
|
const window = text.slice(Math.max(0, start - 160), start);
|
|
1364
1405
|
let cut = 0;
|
|
1365
1406
|
for (const m of window.matchAll(STATEMENT_BREAK))
|
|
1366
1407
|
cut = m.index + m[0].length;
|
|
1367
|
-
|
|
1408
|
+
const statement = window
|
|
1368
1409
|
.slice(cut)
|
|
1369
1410
|
.toLowerCase()
|
|
1370
|
-
.replace(/[`*_~()\[\]
|
|
1371
|
-
|
|
1411
|
+
.replace(/[`*_~()\[\]]/g, ' ');
|
|
1412
|
+
return {
|
|
1413
|
+
words: statement.replace(/[\s,]+/g, ' '),
|
|
1414
|
+
commas: statement.replace(/[\s,]+/g, (run) => (run.includes(',') ? ',' : ' ')),
|
|
1415
|
+
};
|
|
1372
1416
|
}
|
|
1373
1417
|
/**
|
|
1374
1418
|
* The statement after a reference, to the first stop, the stops of a sentence
|