@descent-vtt/spec-brief 0.1.0 → 0.2.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.
- package/CHANGELOG.md +301 -0
- package/README.md +92 -22
- package/dist/archive.d.ts +52 -2
- package/dist/archive.js +205 -37
- package/dist/archive.js.map +1 -1
- package/dist/brief.d.ts +2 -0
- package/dist/brief.js +5 -1
- package/dist/brief.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +48 -14
- package/dist/cli.js.map +1 -1
- package/dist/collisions.d.ts +43 -12
- package/dist/collisions.js +90 -58
- package/dist/collisions.js.map +1 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.js +66 -11
- package/dist/config.js.map +1 -1
- package/dist/corpus.d.ts +21 -1
- package/dist/corpus.js +51 -2
- package/dist/corpus.js.map +1 -1
- package/dist/engine.d.ts +33 -3
- package/dist/engine.js +112 -9
- package/dist/engine.js.map +1 -1
- package/dist/frontmatter.d.ts +18 -61
- package/dist/frontmatter.js +31 -300
- package/dist/frontmatter.js.map +1 -1
- package/dist/glob.d.ts +77 -54
- package/dist/glob.js +104 -433
- package/dist/glob.js.map +1 -1
- package/dist/index.d.ts +10 -8
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/links.d.ts +1 -1
- package/dist/links.js +3 -4
- package/dist/links.js.map +1 -1
- package/dist/lint.d.ts +33 -2
- package/dist/lint.js +9 -2
- package/dist/lint.js.map +1 -1
- package/dist/markdown.d.ts +27 -23
- package/dist/markdown.js +66 -235
- package/dist/markdown.js.map +1 -1
- package/dist/plugins.d.ts +14 -0
- package/dist/plugins.js +142 -6
- package/dist/plugins.js.map +1 -1
- package/dist/report.d.ts +40 -3
- package/dist/report.js +227 -11
- package/dist/report.js.map +1 -1
- package/dist/rules.d.ts +22 -4
- package/dist/rules.js +175 -45
- package/dist/rules.js.map +1 -1
- package/dist/scaffold.d.ts +1 -1
- package/dist/scaffold.js +10 -9
- package/dist/scaffold.js.map +1 -1
- package/dist/schedule.d.ts +133 -0
- package/dist/schedule.js +265 -0
- package/dist/schedule.js.map +1 -0
- package/dist/scope.d.ts +52 -0
- package/dist/scope.js +56 -0
- package/dist/scope.js.map +1 -0
- package/dist/text.d.ts +13 -0
- package/dist/text.js +23 -0
- package/dist/text.js.map +1 -1
- package/dist/trigger.d.ts +17 -0
- package/dist/trigger.js +49 -0
- package/dist/trigger.js.map +1 -0
- package/dist/types.d.ts +14 -5
- package/dist/types.js.map +1 -1
- package/dist/vendor/spec-core/markdown/frontmatter.d.ts +103 -0
- package/dist/vendor/spec-core/markdown/frontmatter.js +459 -0
- package/dist/vendor/spec-core/markdown/frontmatter.js.map +1 -0
- package/dist/vendor/spec-core/markdown/headings.d.ts +45 -0
- package/dist/vendor/spec-core/markdown/headings.js +199 -0
- package/dist/vendor/spec-core/markdown/headings.js.map +1 -0
- package/dist/vendor/spec-core/markdown/index.d.ts +5 -0
- package/dist/vendor/spec-core/markdown/index.js +4 -0
- package/dist/vendor/spec-core/markdown/index.js.map +1 -0
- package/dist/vendor/spec-core/markdown/layout.d.ts +39 -0
- package/dist/vendor/spec-core/markdown/layout.js +28 -0
- package/dist/vendor/spec-core/markdown/layout.js.map +1 -0
- package/dist/vendor/spec-core/markdown/links.d.ts +25 -0
- package/dist/vendor/spec-core/markdown/links.js +394 -0
- package/dist/vendor/spec-core/markdown/links.js.map +1 -0
- package/dist/vendor/spec-core/markdown/lists.d.ts +22 -0
- package/dist/vendor/spec-core/markdown/lists.js +127 -0
- package/dist/vendor/spec-core/markdown/lists.js.map +1 -0
- package/dist/vendor/spec-core/markdown/scan.d.ts +36 -0
- package/dist/vendor/spec-core/markdown/scan.js +463 -0
- package/dist/vendor/spec-core/markdown/scan.js.map +1 -0
- package/dist/vendor/spec-core/markdown/syntax.d.ts +75 -0
- package/dist/vendor/spec-core/markdown/syntax.js +181 -0
- package/dist/vendor/spec-core/markdown/syntax.js.map +1 -0
- package/dist/vendor/spec-core/markdown/tables.d.ts +18 -0
- package/dist/vendor/spec-core/markdown/tables.js +86 -0
- package/dist/vendor/spec-core/markdown/tables.js.map +1 -0
- package/dist/vendor/spec-core/markdown/types.d.ts +290 -0
- package/dist/vendor/spec-core/markdown/types.js +9 -0
- package/dist/vendor/spec-core/markdown/types.js.map +1 -0
- package/dist/vendor/spec-core/path/index.d.ts +1 -0
- package/dist/vendor/spec-core/path/index.js +2 -0
- package/dist/vendor/spec-core/path/index.js.map +1 -0
- package/dist/vendor/spec-core/path/posix.d.ts +83 -0
- package/dist/vendor/spec-core/path/posix.js +150 -0
- package/dist/vendor/spec-core/path/posix.js.map +1 -0
- package/dist/vendor/spec-core/pattern/automaton.d.ts +129 -0
- package/dist/vendor/spec-core/pattern/automaton.js +340 -0
- package/dist/vendor/spec-core/pattern/automaton.js.map +1 -0
- package/dist/vendor/spec-core/pattern/charset.d.ts +58 -0
- package/dist/vendor/spec-core/pattern/charset.js +116 -0
- package/dist/vendor/spec-core/pattern/charset.js.map +1 -0
- package/dist/vendor/spec-core/pattern/glob.d.ts +121 -0
- package/dist/vendor/spec-core/pattern/glob.js +481 -0
- package/dist/vendor/spec-core/pattern/glob.js.map +1 -0
- package/dist/vendor/spec-core/pattern/index.d.ts +6 -0
- package/dist/vendor/spec-core/pattern/index.js +4 -0
- package/dist/vendor/spec-core/pattern/index.js.map +1 -0
- package/dist/vendor/spec-core/pattern/regex.d.ts +67 -0
- package/dist/vendor/spec-core/pattern/regex.js +813 -0
- package/dist/vendor/spec-core/pattern/regex.js.map +1 -0
- package/dist/vendor/spec-core/text/index.d.ts +2 -0
- package/dist/vendor/spec-core/text/index.js +2 -0
- package/dist/vendor/spec-core/text/index.js.map +1 -0
- package/dist/vendor/spec-core/text/lines.d.ts +72 -0
- package/dist/vendor/spec-core/text/lines.js +156 -0
- package/dist/vendor/spec-core/text/lines.js.map +1 -0
- package/package.json +4 -3
- package/schema.json +17 -0
- package/src/vendor/spec-core/LICENSE +21 -0
- package/src/vendor/spec-core/README.md +8 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regex.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/pattern/regex.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A regular-expression matcher that cannot backtrack.\n *\n * Written for spec-graph, whose `~=` selector used to hand a user-supplied\n * string to `RegExp` and wait (spec-graph ADR-0017), and moved here so that\n * every tool that accepts a pattern from configuration or from a document can\n * run it unattended in CI without a pattern deciding how long CI takes.\n *\n * The cost is neither theoretical nor exotic. `^([A-Za-z0-9_]+[ ]?)+$` is what\n * somebody writes to say \"the title is words separated by single spaces\", and\n * against a title that does not match, V8 tries one branch per way of cutting\n * each word into pieces:\n *\n * ```text\n * RegExp here\n * the quick brown fox jumps over the lazy dog! 0.9s 11us\n * the quick brown fox jumps over the lazy dog and! 5.4s 12us\n * the quick brown fox jumps over the lazy dog and keeps! 103s 13us\n * ```\n *\n * So a pattern here is compiled to a non-deterministic finite automaton and\n * simulated over the subject one character at a time (Thompson, 1968), keeping\n * a set of live states instead of a stack of choices. Each state is visited at\n * most once per position, which makes the work O(pattern x subject), growing\n * with the subject and not with the pattern's ambiguity.\n *\n * What it costs is a dialect. Backreferences and lookaround are not regular and\n * have no place in a linear automaton, so they are rejected while compiling,\n * with a message and an offset, rather than accepted and then slow.\n *\n * The dialect is JavaScript's without the `u` flag, character for character,\n * and is held to that by a differential test against `RegExp`: code units,\n * not code points, and `i` folding by the specification's `Canonicalize`.\n * Matching is unanchored and, unless `ignoreCase: false` is passed,\n * case-insensitive, which is what spec-graph's `~=` has always been. There\n * are no captures: nothing asks where a match was, only whether there was one.\n */\n\n/* -------------------------------------------------------------------------- */\n/* Errors */\n/* -------------------------------------------------------------------------- */\n\n/** A pattern that will not compile, and where in it the problem starts. */\nexport class RegexError extends Error {\n /** Offset into the pattern source. */\n readonly offset: number;\n\n constructor(message: string, offset: number) {\n super(message);\n this.name = 'RegexError';\n this.offset = offset;\n }\n}\n\n/**\n * Ceiling on the compiled program.\n *\n * Counted repetition is compiled by copying - `(ab){20}` is twenty copies -\n * which is part of what keeps the simulation flat, and also what makes\n * `(a{99}){99}` into ten thousand states. The bound has to live somewhere, and\n * a number checked while compiling is the only place it can be enforced without\n * measuring anything at match time.\n *\n * Far above any real selector: the widest pattern in this repository's own\n * tests compiles to seventeen states.\n */\nconst MAX_PROGRAM = 4096;\n\n/* -------------------------------------------------------------------------- */\n/* Character sets */\n/* -------------------------------------------------------------------------- */\n\n/** An inclusive range of UTF-16 code units. */\ntype Range = readonly [number, number];\n\n/**\n * A set of code units, as inclusive ranges.\n *\n * Code units rather than code points, because that is what a `RegExp` without\n * the `u` flag matches: `.` consumes one half of a surrogate pair, and so does\n * this. Agreeing with the engine this replaced matters more than being right\n * about astral planes, which no selector in any corpus has asked about.\n */\ninterface CharSet {\n readonly negated: boolean;\n readonly ranges: readonly Range[];\n}\n\n/** `.` - anything but a line terminator, which is the default `RegExp` reading. */\nconst DOT: CharSet = { negated: true, ranges: [[0x0a, 0x0a], [0x0d, 0x0d], [0x2028, 0x2029]] };\nconst DIGIT: readonly Range[] = [[0x30, 0x39]];\nconst WORD: readonly Range[] = [\n [0x30, 0x39],\n [0x41, 0x5a],\n [0x5f, 0x5f],\n [0x61, 0x7a],\n];\n/** `\\s`, taken from the specification rather than guessed at. */\nconst SPACE: readonly Range[] = [\n [0x09, 0x0d],\n [0x20, 0x20],\n [0xa0, 0xa0],\n [0x1680, 0x1680],\n [0x2000, 0x200a],\n [0x2028, 0x2029],\n [0x202f, 0x202f],\n [0x205f, 0x205f],\n [0x3000, 0x3000],\n [0xfeff, 0xfeff],\n];\n\n/**\n * Folds a code unit the way a case-insensitive `RegExp` does.\n *\n * This is `Canonicalize` from the language specification, non-Unicode mode:\n * upper-case the character, keep it unchanged if that produced anything other\n * than one code unit, and keep it unchanged if upper-casing dragged a\n * non-ASCII character into ASCII. The last clause is the one nobody expects and\n * the reason U+017F (long s) does not match `s`.\n */\nfunction canonical(code: number): number {\n // Every subject a glob sees is mostly ASCII, where the answer needs no string.\n // The general path below gives the same answer here, only slower.\n if (code < 128) return code >= 97 && code <= 122 ? code - 32 : code;\n const upper = String.fromCharCode(code).toUpperCase();\n if (upper.length !== 1) return code;\n const folded = upper.charCodeAt(0);\n if (code >= 128 && folded < 128) return code;\n return folded;\n}\n\n/**\n * Whether a set accepts a code unit, case-insensitively.\n *\n * The specification canonicalises both sides: a character matches a set when\n * *some* member of the set folds to the same thing it does. A single-character\n * member can be asked that exactly. A range cannot without a fold table for\n * every code unit, so a range is asked the question backwards - does the\n * character, or either of its own case forms, fall inside it - which is exact\n * for every character whose fold is its own case change, and therefore for\n * every range anyone has written.\n */\nfunction accepts(set: CharSet, code: number): boolean {\n const folded = canonical(code);\n let hit = false;\n for (let i = 0; i < set.ranges.length; i += 1) {\n const [low, high] = set.ranges[i] as Range;\n if (low === high ? low === code || canonical(low) === folded : inRange(low, high, code)) {\n hit = true;\n break;\n }\n }\n return set.negated ? !hit : hit;\n}\n\n/**\n * Whether some member of a range folds to the same thing a code unit does.\n *\n * Asked backwards, by trying the character's own case forms against the raw\n * range - and then checking that the form found there really does fold to the\n * same place, which is the part that is easy to leave out. U+017F upper-cases\n * to `S`, so without that check it matches `[A-Z]`, and it must not: the fold\n * keeps it outside ASCII, which is the same clause `isWordChar` gets wrong if\n * nobody is watching. The differential corpus caught both.\n */\nfunction inRange(low: number, high: number, code: number): boolean {\n if (code >= low && code <= high) return true;\n // An ASCII character's only other case form is its ASCII letter twin, and the\n // two always fold together - so the loop below would ask exactly this.\n if (code < 128) {\n const twin = code >= 65 && code <= 90 ? code + 32 : code >= 97 && code <= 122 ? code - 32 : -1;\n return twin >= low && twin <= high;\n }\n const folded = canonical(code);\n const char = String.fromCharCode(code);\n for (const variant of [char.toLowerCase(), char.toUpperCase()]) {\n if (variant.length !== 1) continue;\n const candidate = variant.charCodeAt(0);\n if (candidate >= low && candidate <= high && canonical(candidate) === folded) return true;\n }\n return false;\n}\n\n/**\n * Whether a set accepts a code unit as written.\n *\n * What `RegExp` does without the `i` flag, and so none of the folding above\n * applies - which also means none of its one divergence does.\n */\nfunction acceptsExactly(set: CharSet, code: number): boolean {\n return within(set.ranges, code) !== set.negated;\n}\n\nfunction within(ranges: readonly Range[], code: number): boolean {\n for (let i = 0; i < ranges.length; i += 1) {\n const range = ranges[i] as Range;\n if (code >= range[0] && code <= range[1]) return true;\n }\n return false;\n}\n\n/**\n * Word characters for `\\b`, which is exactly `\\w` here.\n *\n * The specification does widen this set under case-insensitivity - to every\n * character that folds into it, which is U+017F (long s) and U+212A (the\n * Kelvin sign) - but only in Unicode mode, where `Canonicalize` has no clause\n * keeping a non-ASCII character out of ASCII. This is the non-Unicode dialect,\n * so both stay outside and the table for `\\w` answers for `\\b` as well.\n *\n * Written down because the first version of this function widened the set, and\n * the differential test against `RegExp` is what said otherwise. Reading the\n * clause was not enough; running it was. See spec-graph ADR-0017.\n */\nfunction isWordChar(code: number): boolean {\n return within(WORD, code);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Syntax tree */\n/* -------------------------------------------------------------------------- */\n\ntype Assertion = 'start' | 'end' | 'word-boundary' | 'not-word-boundary';\n\ntype Node =\n | { readonly kind: 'empty' }\n | { readonly kind: 'char'; readonly set: CharSet }\n | { readonly kind: 'assert'; readonly assertion: Assertion }\n | { readonly kind: 'concat'; readonly parts: readonly Node[] }\n | { readonly kind: 'alternate'; readonly options: readonly Node[] }\n | { readonly kind: 'repeat'; readonly node: Node; readonly min: number; readonly max: number };\n\n/* -------------------------------------------------------------------------- */\n/* Parsing */\n/* -------------------------------------------------------------------------- */\n\nclass PatternParser {\n private readonly source: string;\n private position = 0;\n\n constructor(source: string) {\n this.source = source;\n }\n\n parse(): Node {\n const node = this.parseAlternation();\n // Every character is an atom except the two that close something, and\n // `parseSequence` stops on both, so anything left over is an unopened `)`.\n if (this.position < this.source.length) throw new RegexError('unmatched \")\"', this.position);\n return node;\n }\n\n private parseAlternation(): Node {\n const options: Node[] = [this.parseSequence()];\n while (this.peek() === '|') {\n this.position += 1;\n options.push(this.parseSequence());\n }\n return options.length === 1 ? (options[0] as Node) : { kind: 'alternate', options };\n }\n\n private parseSequence(): Node {\n const parts: Node[] = [];\n for (;;) {\n const char = this.peek();\n if (char === undefined || char === '|' || char === ')') break;\n parts.push(this.parseQuantified());\n }\n if (parts.length === 0) return { kind: 'empty' };\n return parts.length === 1 ? (parts[0] as Node) : { kind: 'concat', parts };\n }\n\n private parseQuantified(): Node {\n const start = this.position;\n // A group makes its contents quantifiable: `RegExp` rejects `\\b*` and\n // accepts `(\\b)*`, which is the same nothing said twice, and this parser\n // treats a group as transparent - so whether one was written is the only\n // thing left that distinguishes the two.\n const grouped = this.peek() === '(';\n const atom = this.parseAtom();\n const bounds = this.parseQuantifier();\n if (bounds === null) return atom;\n if (atom.kind === 'assert' && !grouped) {\n throw new RegexError('nothing to repeat: a quantifier cannot follow an anchor', start);\n }\n return { kind: 'repeat', node: atom, min: bounds.min, max: bounds.max };\n }\n\n /** `*`, `+`, `?`, `{n}`, `{n,}`, `{n,m}`, and a trailing `?` that is ignored. */\n private parseQuantifier(): { min: number; max: number } | null {\n const char = this.peek();\n let bounds: { min: number; max: number } | null = null;\n\n if (char === '*') bounds = { min: 0, max: Infinity };\n else if (char === '+') bounds = { min: 1, max: Infinity };\n else if (char === '?') bounds = { min: 0, max: 1 };\n\n if (bounds !== null) this.position += 1;\n else if (char === '{') bounds = this.parseBraces();\n if (bounds === null) return null;\n\n // Laziness decides *which* match is found, and nothing here asks: the\n // question is whether one exists, and a lazy quantifier accepts the same\n // language as a greedy one.\n if (this.peek() === '?') this.position += 1;\n return bounds;\n }\n\n /**\n * Reads `{n,m}`, or nothing.\n *\n * A `{` that does not open a counted repetition is a literal brace, which is\n * what `RegExp` does with `a{` and what any pattern written against a\n * document full of `{0}` placeholders depends on.\n */\n private parseBraces(): { min: number; max: number } | null {\n const match = /^\\{(\\d+)(?:(,)(\\d*))?\\}/.exec(this.source.slice(this.position));\n if (!match) return null;\n const min = Number(match[1]);\n const max = match[2] === undefined ? min : match[3] === '' ? Infinity : Number(match[3]);\n if (min > max) throw new RegexError('numbers out of order in a counted repetition', this.position);\n this.position += (match[0] as string).length;\n return { min, max };\n }\n\n private parseAtom(): Node {\n const start = this.position;\n const char = this.peek();\n\n switch (char) {\n case undefined:\n throw new RegexError('pattern ends where an expression was expected', start);\n case '(':\n return this.parseGroup();\n case '[':\n return { kind: 'char', set: this.parseClass() };\n case '.':\n this.position += 1;\n return { kind: 'char', set: DOT };\n case '^':\n this.position += 1;\n return { kind: 'assert', assertion: 'start' };\n case '$':\n this.position += 1;\n return { kind: 'assert', assertion: 'end' };\n case '*':\n case '+':\n throw new RegexError(`nothing to repeat before \"${char}\"`, start);\n case '\\\\':\n return this.parseEscape();\n default:\n this.position += 1;\n return { kind: 'char', set: literal(char.charCodeAt(0)) };\n }\n }\n\n /**\n * A group, which is never a capture.\n *\n * `(a)` and `(?:a)` compile to the same automaton because nothing downstream\n * can ask what `(a)` caught. A named group is accepted and its name dropped,\n * so a pattern copied out of somewhere else keeps working.\n */\n private parseGroup(): Node {\n const start = this.position;\n this.position += 1;\n\n if (this.source.startsWith('?:', this.position)) {\n this.position += 2;\n } else if (this.peek() === '?') {\n const named = /^\\?<([A-Za-z_$][\\w$]*)>/.exec(this.source.slice(this.position));\n if (named) {\n this.position += (named[0] as string).length;\n } else if (/^\\?(?:=|!|<=|<!)/.test(this.source.slice(this.position))) {\n throw new RegexError(\n 'lookaround is not supported: an automaton that cannot backtrack cannot look ahead - use ^= $= or *= for a fixed prefix, suffix or substring',\n start,\n );\n } else {\n throw new RegexError('unsupported group: expected (?:...) or (?<name>...)', start);\n }\n }\n\n const inner = this.parseAlternation();\n if (this.peek() !== ')') throw new RegexError('unmatched \"(\"', start);\n this.position += 1;\n return inner;\n }\n\n /**\n * Reads a `[...]` class.\n *\n * `[]` matches nothing and `[^]` matches anything, which reads like a mistake\n * and is what every JavaScript engine does: the class ends at the first `]`,\n * even when that `]` is the first character inside it.\n */\n private parseClass(): CharSet {\n const start = this.position;\n this.position += 1;\n const negated = this.peek() === '^';\n if (negated) this.position += 1;\n\n const ranges: Range[] = [];\n while (this.position < this.source.length && this.peek() !== ']') {\n const low = this.parseClassAtom();\n // A `-` between two single characters is a range. Anywhere else - at\n // either end of the class, or beside a `\\d`-style set, which has no\n // endpoint - it is a literal hyphen, exactly as Annex B has it.\n if (this.peek() !== '-' || this.source[this.position + 1] === ']' || this.position + 1 >= this.source.length) {\n push(ranges, low);\n continue;\n }\n const dash = this.position;\n this.position += 1;\n const high = this.parseClassAtom();\n if (typeof low === 'number' && typeof high === 'number') {\n if (low > high) throw new RegexError('characters out of order in a character class', dash);\n ranges.push([low, high]);\n continue;\n }\n push(ranges, low);\n ranges.push([0x2d, 0x2d]);\n push(ranges, high);\n }\n\n if (this.peek() !== ']') throw new RegexError('unterminated character class', start);\n this.position += 1;\n return { negated, ranges };\n }\n\n /** One member of a class: a code unit, or a whole set for `\\d` and its kind. */\n private parseClassAtom(): number | readonly Range[] {\n if (this.peek() !== '\\\\') {\n const code = (this.peek() as string).charCodeAt(0);\n this.position += 1;\n return code;\n }\n // `\\b` is a backspace inside a class and a word boundary outside one, which\n // is the only place the two readings of an escape diverge.\n if (this.source[this.position + 1] === 'b') {\n this.position += 2;\n return 0x08;\n }\n if (this.source[this.position + 1] === 'B') {\n throw new RegexError('\"\\\\B\" is an assertion, not a character, so it cannot be in a class', this.position);\n }\n const set = this.parseCharacterEscape();\n if (!set.negated && set.ranges.length === 1) {\n const [low, high] = set.ranges[0] as Range;\n if (low === high) return low;\n }\n return set.negated ? invert(set.ranges) : set.ranges;\n }\n\n /** An escape outside a class, where `\\b` and `\\B` are assertions. */\n private parseEscape(): Node {\n const next = this.source[this.position + 1];\n if (next === 'b' || next === 'B') {\n this.position += 2;\n return { kind: 'assert', assertion: next === 'b' ? 'word-boundary' : 'not-word-boundary' };\n }\n return { kind: 'char', set: this.parseCharacterEscape() };\n }\n\n /** Every escape that stands for a character or a set of them. */\n private parseCharacterEscape(): CharSet {\n const start = this.position;\n this.position += 1;\n const char = this.peek();\n if (char === undefined) throw new RegexError('pattern ends with a backslash', start);\n this.position += 1;\n\n switch (char) {\n case 'd':\n return { negated: false, ranges: DIGIT };\n case 'D':\n return { negated: true, ranges: DIGIT };\n case 'w':\n return { negated: false, ranges: WORD };\n case 'W':\n return { negated: true, ranges: WORD };\n case 's':\n return { negated: false, ranges: SPACE };\n case 'S':\n return { negated: true, ranges: SPACE };\n case 'n':\n return literal(0x0a);\n case 'r':\n return literal(0x0d);\n case 't':\n return literal(0x09);\n case 'f':\n return literal(0x0c);\n case 'v':\n return literal(0x0b);\n case '0':\n if (/^\\d/.test(this.source.slice(this.position))) {\n throw new RegexError('an octal escape is not supported - write \\\\xHH or \\\\uHHHH', start);\n }\n return literal(0);\n case 'x':\n return literal(this.readHex(2, start));\n case 'u':\n return literal(this.readHex(4, start));\n case 'c': {\n const letter = this.peek();\n if (letter === undefined || !/[A-Za-z]/.test(letter)) {\n throw new RegexError('expected a letter after \"\\\\c\"', start);\n }\n this.position += 1;\n return literal(letter.charCodeAt(0) % 32);\n }\n case 'k':\n throw new RegexError(\n 'a named backreference is not supported: a backreference is not a regular expression, and this is an automaton',\n start,\n );\n case 'p':\n case 'P':\n throw new RegexError(\n `\"\\\\${char}\" needs a table of Unicode properties, which this matcher does not carry - write the characters out as a [class]`,\n start,\n );\n default:\n if (/[1-9]/.test(char)) {\n throw new RegexError(\n 'a backreference is not supported: it is not a regular expression, and this is an automaton',\n start,\n );\n }\n if (/[A-Za-z]/.test(char)) {\n // `RegExp` reads an unknown letter escape as the letter itself, so\n // `\\A` quietly matches a capital A and `\\z` a lower-case z. Saying so\n // is worth more than agreeing with a rule nobody wanted.\n throw new RegexError(`unknown escape \"\\\\${char}\"`, start);\n }\n return literal(char.charCodeAt(0));\n }\n }\n\n private readHex(digits: number, start: number): number {\n const raw = this.source.slice(this.position, this.position + digits);\n if (raw.length !== digits || !/^[0-9a-fA-F]+$/.test(raw)) {\n throw new RegexError(`expected ${digits} hex digits after \"\\\\${this.source[start + 1] as string}\"`, start);\n }\n this.position += digits;\n return Number.parseInt(raw, 16);\n }\n\n private peek(): string | undefined {\n return this.source[this.position];\n }\n}\n\nfunction literal(code: number): CharSet {\n return { negated: false, ranges: [[code, code]] };\n}\n\nfunction push(ranges: Range[], atom: number | readonly Range[]): void {\n if (typeof atom === 'number') ranges.push([atom, atom]);\n else ranges.push(...atom);\n}\n\n/**\n * Complement of a range list, so `[\\D]` can sit inside a class.\n *\n * A negated escape is a set with no endpoints, and a class is a union of\n * ranges, so the only way to put one inside the other is to spell out what it\n * leaves.\n */\nfunction invert(ranges: readonly Range[]): readonly Range[] {\n const sorted = [...ranges].sort((a, b) => a[0] - b[0]);\n const out: Range[] = [];\n let cursor = 0;\n for (const [low, high] of sorted) {\n if (low > cursor) out.push([cursor, low - 1]);\n cursor = Math.max(cursor, high + 1);\n }\n if (cursor <= 0xffff) out.push([cursor, 0xffff]);\n return out;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Compilation */\n/* -------------------------------------------------------------------------- */\n\ninterface Split {\n readonly op: 'split';\n /** Where the first branch starts. */\n x: number;\n /** Where the second branch starts. */\n y: number;\n}\n\ninterface Jump {\n readonly op: 'jump';\n to: number;\n}\n\ntype Instruction =\n | { readonly op: 'char'; readonly set: CharSet }\n | Split\n | Jump\n | { readonly op: 'assert'; readonly assertion: Assertion }\n | { readonly op: 'match' };\n\nclass Compiler {\n readonly code: Instruction[] = [];\n\n private add<T extends Instruction>(instruction: T): T {\n if (this.code.length >= MAX_PROGRAM) {\n throw new RegexError(\n `pattern is too large: counted repetition is compiled by copying, and this needs more than ${MAX_PROGRAM} states`,\n 0,\n );\n }\n this.code.push(instruction);\n return instruction;\n }\n\n get here(): number {\n return this.code.length;\n }\n\n emitMatch(): void {\n this.add({ op: 'match' });\n }\n\n compile(node: Node): void {\n switch (node.kind) {\n case 'empty':\n return;\n case 'char':\n this.add({ op: 'char', set: node.set });\n return;\n case 'assert':\n this.add({ op: 'assert', assertion: node.assertion });\n return;\n case 'concat':\n for (const part of node.parts) this.compile(part);\n return;\n case 'alternate': {\n // One split per option but the last. Each split falls through to its\n // own branch and points its second arm at the next split; each branch\n // ends in a jump past all of them.\n const ends: Jump[] = [];\n for (let i = 0; i < node.options.length - 1; i += 1) {\n const split = this.add({ op: 'split', x: 0, y: 0 });\n split.x = this.here;\n this.compile(node.options[i] as Node);\n ends.push(this.add({ op: 'jump', to: 0 }));\n split.y = this.here;\n }\n this.compile(node.options[node.options.length - 1] as Node);\n for (const end of ends) end.to = this.here;\n return;\n }\n case 'repeat':\n this.repeat(node.node, node.min, node.max);\n return;\n }\n }\n\n private repeat(node: Node, min: number, max: number): void {\n for (let i = 0; i < min; i += 1) this.compile(node);\n\n if (max === Infinity) {\n const split = this.add({ op: 'split', x: 0, y: 0 });\n const body = this.here;\n split.x = body;\n this.compile(node);\n this.add({ op: 'jump', to: body - 1 });\n split.y = this.here;\n return;\n }\n\n // `{2,5}` is two copies and then three optional ones, each able to leave\n // for the far end rather than for the next copy.\n const exits: Split[] = [];\n for (let i = min; i < max; i += 1) {\n const split = this.add({ op: 'split', x: 0, y: 0 });\n split.x = this.here;\n exits.push(split);\n this.compile(node);\n }\n for (const split of exits) split.y = this.here;\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Simulation */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A compiled pattern. Reusable and safe to cache.\n *\n * Not reentrant, which nothing can ask of it: `test` is synchronous and calls\n * out to nothing, and the buffers it keeps between subjects are what make it\n * cheap enough to run against every path a walk visits.\n */\nexport interface RegexMatcher {\n /** True when the pattern matches anywhere in the subject. */\n test(subject: string): boolean;\n /** State count. Published for the size test, and for nothing else. */\n readonly size: number;\n}\n\nexport interface RegexOptions {\n /** Fold case the way the `i` flag does. On unless set to `false`. */\n readonly ignoreCase?: boolean | undefined;\n}\n\n/**\n * Compiles a pattern into a matcher.\n *\n * Throws {@link RegexError} on anything it cannot run in linear time, which\n * is the point: the alternative to a message here is a build that stops.\n */\nexport function compileRegex(source: string, options: RegexOptions = {}): RegexMatcher {\n const tree = new PatternParser(source).parse();\n const compiler = new Compiler();\n compiler.compile(tree);\n compiler.emitMatch();\n // A pattern that begins by asserting the start of the subject cannot match\n // anywhere else, so the simulation stops seeding new threads at every\n // position. Nothing depends on this being noticed - it is the difference\n // between one pass and two over a long body.\n const machine = new Machine(compiler.code, startsAnchored(tree), options.ignoreCase !== false);\n return {\n size: compiler.code.length,\n test: (subject: string): boolean => machine.test(subject),\n };\n}\n\n/** True when every path through the pattern opens by asserting the start. */\nfunction startsAnchored(node: Node): boolean {\n switch (node.kind) {\n case 'assert':\n return node.assertion === 'start';\n case 'concat': {\n const first = node.parts[0];\n return first !== undefined && startsAnchored(first);\n }\n case 'alternate':\n return node.options.every((option) => startsAnchored(option));\n case 'repeat':\n return node.min > 0 && startsAnchored(node.node);\n default:\n return false;\n }\n}\n\nconst OP_CHAR = 0;\nconst OP_SPLIT = 1;\nconst OP_JUMP = 2;\nconst OP_ASSERT = 3;\nconst OP_MATCH = 4;\n\n/** Fills the slots of states that are not characters, where nothing reads it. */\nconst NOTHING: CharSet = { negated: false, ranges: [] };\n\n/**\n * The simulation, over the program flattened into typed arrays.\n *\n * The compiler's instructions are objects of five shapes, and one loop reading\n * `op` off all five is a megamorphic property read on every step. Simulated that\n * way, with a fresh visited table per subject, a glob cost about 3.5\n * microseconds a path and a path that failed on its first character still paid\n * half a microsecond for the allocation. Flat arrays and buffers kept between\n * subjects bring those to 0.6 and 0.04 - `RegExp` takes 0.06 - which matters\n * because a walk tests every path it visits against every pattern.\n */\nclass Machine {\n private readonly ops: Uint8Array;\n /** A split's first branch, or a jump's target. */\n private readonly first: Int32Array;\n /** A split's second branch. */\n private readonly second: Int32Array;\n private readonly sets: CharSet[];\n private readonly assertions: Assertion[];\n private readonly anchored: boolean;\n private readonly ignoreCase: boolean;\n\n /**\n * The position each state was last reached at. One visit per state per\n * position is exactly what turns the exponent into a product.\n */\n private readonly visited: Int32Array;\n /** Each visit pushes at most two states, so this cannot overflow. */\n private readonly stack: Int32Array;\n private live: Int32Array;\n private next: Int32Array;\n\n constructor(code: readonly Instruction[], anchored: boolean, ignoreCase: boolean) {\n const size = code.length;\n this.ops = new Uint8Array(size);\n this.first = new Int32Array(size);\n this.second = new Int32Array(size);\n this.sets = new Array<CharSet>(size).fill(NOTHING);\n this.assertions = new Array<Assertion>(size).fill('start');\n this.anchored = anchored;\n this.ignoreCase = ignoreCase;\n this.visited = new Int32Array(size).fill(-1);\n this.stack = new Int32Array(2 * size + 1);\n this.live = new Int32Array(size);\n this.next = new Int32Array(size);\n\n code.forEach((instruction, pc) => {\n switch (instruction.op) {\n case 'char':\n this.ops[pc] = OP_CHAR;\n this.sets[pc] = instruction.set;\n break;\n case 'split':\n this.ops[pc] = OP_SPLIT;\n this.first[pc] = instruction.x;\n this.second[pc] = instruction.y;\n break;\n case 'jump':\n this.ops[pc] = OP_JUMP;\n this.first[pc] = instruction.to;\n break;\n case 'assert':\n this.ops[pc] = OP_ASSERT;\n this.assertions[pc] = instruction.assertion;\n break;\n case 'match':\n this.ops[pc] = OP_MATCH;\n break;\n }\n });\n }\n\n test(subject: string): boolean {\n const length = subject.length;\n this.visited.fill(-1);\n\n let live = this.live;\n let next = this.next;\n let alive = 0;\n\n for (let position = 0; position <= length; position += 1) {\n if (position === 0 || !this.anchored) {\n alive = this.seed(live, alive, 0, subject, position);\n if (alive < 0) return true;\n } else if (alive === 0) {\n // An anchored pattern gets one chance, and every thread from it has died.\n return false;\n }\n\n if (position === length) return false;\n const char = subject.charCodeAt(position);\n let arriving = 0;\n for (let i = 0; i < alive; i += 1) {\n const pc = live[i] as number;\n const set = this.sets[pc] as CharSet;\n if (!(this.ignoreCase ? accepts(set, char) : acceptsExactly(set, char))) continue;\n arriving = this.seed(next, arriving, pc + 1, subject, position + 1);\n if (arriving < 0) return true;\n }\n const spent = live;\n live = next;\n next = spent;\n alive = arriving;\n }\n\n return false;\n }\n\n /**\n * Follows every zero-width transition out of one state, appending the\n * character states it reaches to `list`.\n *\n * Returns the new length of the list, or -1 the moment a thread reaches the\n * end of the pattern: the only question is whether a match exists, so there\n * is no leftmost-longest to settle and no captures to keep, and the first\n * thread to arrive is the answer.\n *\n * A stray thread at state 0 changes no answer: an unanchored pattern seeds it\n * at every position anyway, and an anchored one opens by asserting the start.\n * That makes two mutants here equivalent, with no test to write - the loop\n * running once past an empty stack, and a jump read as a split, both of which\n * add exactly that thread.\n */\n private seed(list: Int32Array, length: number, start: number, subject: string, position: number): number {\n const { ops, first, second, visited, stack } = this;\n let count = length;\n let top = 0;\n stack[top++] = start;\n while (top > 0) {\n const pc = stack[--top] as number;\n if (visited[pc] === position) continue;\n visited[pc] = position;\n switch (ops[pc]) {\n case OP_MATCH:\n return -1;\n case OP_JUMP:\n stack[top++] = first[pc] as number;\n break;\n case OP_SPLIT:\n stack[top++] = second[pc] as number;\n stack[top++] = first[pc] as number;\n break;\n case OP_ASSERT:\n if (holds(this.assertions[pc] as Assertion, subject, position)) stack[top++] = pc + 1;\n break;\n default:\n list[count++] = pc;\n }\n }\n return count;\n }\n}\n\nfunction holds(assertion: Assertion, subject: string, position: number): boolean {\n switch (assertion) {\n case 'start':\n return position === 0;\n case 'end':\n return position === subject.length;\n default: {\n const before = position > 0 && isWordChar(subject.charCodeAt(position - 1));\n const after = position < subject.length && isWordChar(subject.charCodeAt(position));\n return (before !== after) === (assertion === 'word-boundary');\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/text/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,QAAQ,EACR,UAAU,EACV,UAAU,EACV,MAAM,EACN,UAAU,EACV,WAAW,EACX,UAAU,EACV,QAAQ,GACT,MAAM,YAAY,CAAC","sourcesContent":["export {\n createLineIndex,\n inRanges,\n lineEnding,\n lineStarts,\n locate,\n maskRanges,\n mergeRanges,\n splitLines,\n stripBom,\n} from './lines.js';\nexport type { LineIndex, Position, Range } from './lines.js';\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lines, offsets and masks.
|
|
3
|
+
*
|
|
4
|
+
* Every finding a spec-* tool reports points at a line and a column, and every
|
|
5
|
+
* structure the scanner builds carries raw offsets rather than copies of the
|
|
6
|
+
* text. Converting between the two is on the hot path, so the line table is
|
|
7
|
+
* built once per file and searched by bisection.
|
|
8
|
+
*
|
|
9
|
+
* All three line terminators end a line - `\n`, `\r\n` and a lone `\r`, as
|
|
10
|
+
* CommonMark has it - and `\r\n` counts once. A Windows checkout of a document
|
|
11
|
+
* must produce the line numbers a POSIX checkout does.
|
|
12
|
+
*/
|
|
13
|
+
export interface Position {
|
|
14
|
+
/** UTF-16 offset into the text. */
|
|
15
|
+
readonly offset: number;
|
|
16
|
+
/** 1-based. */
|
|
17
|
+
readonly line: number;
|
|
18
|
+
/** 1-based, in UTF-16 code units. */
|
|
19
|
+
readonly column: number;
|
|
20
|
+
}
|
|
21
|
+
export interface LineIndex {
|
|
22
|
+
/** Number of lines. A final terminator does not open a line of its own. */
|
|
23
|
+
readonly lineCount: number;
|
|
24
|
+
/** Offset at which a 1-based line starts. Out-of-range lines are clamped. */
|
|
25
|
+
lineStart(line: number): number;
|
|
26
|
+
/** Offset just past a 1-based line, before its terminator. */
|
|
27
|
+
lineEnd(line: number): number;
|
|
28
|
+
/** A 1-based line without its terminator. */
|
|
29
|
+
lineText(line: number): string;
|
|
30
|
+
/** The line and column of an offset. Out-of-range offsets are clamped. */
|
|
31
|
+
positionAt(offset: number): Position;
|
|
32
|
+
}
|
|
33
|
+
/** Offsets at which each line starts; index 0 is line 1. */
|
|
34
|
+
export declare function lineStarts(text: string): number[];
|
|
35
|
+
/** Builds the line table for a text. */
|
|
36
|
+
export declare function createLineIndex(text: string): LineIndex;
|
|
37
|
+
/**
|
|
38
|
+
* The line and column of an offset, by bisection over a line table.
|
|
39
|
+
*
|
|
40
|
+
* The search is half-open: `high` is one past the last candidate, and it
|
|
41
|
+
* narrows until one is left. There is no `- 1` to get wrong.
|
|
42
|
+
*/
|
|
43
|
+
export declare function locate(starts: readonly number[], offset: number): Position;
|
|
44
|
+
/** A half-open range of offsets. */
|
|
45
|
+
export interface Range {
|
|
46
|
+
readonly start: number;
|
|
47
|
+
readonly end: number;
|
|
48
|
+
}
|
|
49
|
+
/** Sorts and merges ranges; touching ranges merge. Empty ranges vanish. */
|
|
50
|
+
export declare function mergeRanges(ranges: readonly Range[]): Range[];
|
|
51
|
+
/** Whether an offset lies in one of a list of merged, sorted ranges. */
|
|
52
|
+
export declare function inRanges(merged: readonly Range[], offset: number): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Blanks the given ranges with spaces, keeping every other character and
|
|
55
|
+
* every line terminator where it was.
|
|
56
|
+
*
|
|
57
|
+
* Offsets survive a mask, which is the point: something found at offset 400
|
|
58
|
+
* of the masked text is at offset 400 of the original, on the same line. The
|
|
59
|
+
* replacement walks UTF-16 code units, so a surrogate pair becomes two spaces
|
|
60
|
+
* and every later offset still lands where it did.
|
|
61
|
+
*/
|
|
62
|
+
export declare function maskRanges(text: string, ranges: readonly Range[]): string;
|
|
63
|
+
/** A text without a leading byte-order mark. */
|
|
64
|
+
export declare function stripBom(text: string): string;
|
|
65
|
+
/** The terminator a text mostly uses; `\n` when it has none or they tie. */
|
|
66
|
+
export declare function lineEnding(text: string): '\n' | '\r\n';
|
|
67
|
+
/**
|
|
68
|
+
* The lines of a text, without terminators. Unlike the line table, a final
|
|
69
|
+
* terminator does produce a last, empty line, so that joining the lines with
|
|
70
|
+
* the same terminator gives the text back byte for byte.
|
|
71
|
+
*/
|
|
72
|
+
export declare function splitLines(text: string): string[];
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lines, offsets and masks.
|
|
3
|
+
*
|
|
4
|
+
* Every finding a spec-* tool reports points at a line and a column, and every
|
|
5
|
+
* structure the scanner builds carries raw offsets rather than copies of the
|
|
6
|
+
* text. Converting between the two is on the hot path, so the line table is
|
|
7
|
+
* built once per file and searched by bisection.
|
|
8
|
+
*
|
|
9
|
+
* All three line terminators end a line - `\n`, `\r\n` and a lone `\r`, as
|
|
10
|
+
* CommonMark has it - and `\r\n` counts once. A Windows checkout of a document
|
|
11
|
+
* must produce the line numbers a POSIX checkout does.
|
|
12
|
+
*/
|
|
13
|
+
const LF = 10;
|
|
14
|
+
const CR = 13;
|
|
15
|
+
/** Offsets at which each line starts; index 0 is line 1. */
|
|
16
|
+
export function lineStarts(text) {
|
|
17
|
+
const starts = [0];
|
|
18
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
19
|
+
const ch = text.charCodeAt(i);
|
|
20
|
+
if (ch === LF) {
|
|
21
|
+
starts.push(i + 1);
|
|
22
|
+
}
|
|
23
|
+
else if (ch === CR) {
|
|
24
|
+
if (text.charCodeAt(i + 1) === LF)
|
|
25
|
+
i += 1;
|
|
26
|
+
starts.push(i + 1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// A terminator at the very end opens a line that holds nothing; an editor
|
|
30
|
+
// does not count it, and neither does this.
|
|
31
|
+
if (starts.length > 1 && starts[starts.length - 1] === text.length)
|
|
32
|
+
starts.pop();
|
|
33
|
+
return starts;
|
|
34
|
+
}
|
|
35
|
+
/** Builds the line table for a text. */
|
|
36
|
+
export function createLineIndex(text) {
|
|
37
|
+
const starts = lineStarts(text);
|
|
38
|
+
const lineCount = starts.length;
|
|
39
|
+
const clamp = (line) => (line < 1 ? 1 : line > lineCount ? lineCount : line);
|
|
40
|
+
const startOf = (line) => starts[clamp(line) - 1];
|
|
41
|
+
const endOf = (line) => {
|
|
42
|
+
const index = clamp(line);
|
|
43
|
+
const start = starts[index - 1];
|
|
44
|
+
let end = index === lineCount ? text.length : starts[index];
|
|
45
|
+
// At most two terminator characters, and never past the line's own start.
|
|
46
|
+
if (end > start && text.charCodeAt(end - 1) === LF)
|
|
47
|
+
end -= 1;
|
|
48
|
+
if (end > start && text.charCodeAt(end - 1) === CR)
|
|
49
|
+
end -= 1;
|
|
50
|
+
return end;
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
lineCount,
|
|
54
|
+
lineStart: startOf,
|
|
55
|
+
lineEnd: endOf,
|
|
56
|
+
lineText: (line) => text.slice(startOf(line), endOf(line)),
|
|
57
|
+
positionAt: (offset) => locate(starts, offset < 0 ? 0 : offset > text.length ? text.length : offset),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The line and column of an offset, by bisection over a line table.
|
|
62
|
+
*
|
|
63
|
+
* The search is half-open: `high` is one past the last candidate, and it
|
|
64
|
+
* narrows until one is left. There is no `- 1` to get wrong.
|
|
65
|
+
*/
|
|
66
|
+
export function locate(starts, offset) {
|
|
67
|
+
let low = 0;
|
|
68
|
+
let high = starts.length;
|
|
69
|
+
while (high - low > 1) {
|
|
70
|
+
const mid = (low + high) >> 1;
|
|
71
|
+
if (starts[mid] <= offset)
|
|
72
|
+
low = mid;
|
|
73
|
+
else
|
|
74
|
+
high = mid;
|
|
75
|
+
}
|
|
76
|
+
return { offset, line: low + 1, column: offset - starts[low] + 1 };
|
|
77
|
+
}
|
|
78
|
+
/** Sorts and merges ranges; touching ranges merge. Empty ranges vanish. */
|
|
79
|
+
export function mergeRanges(ranges) {
|
|
80
|
+
const sorted = ranges.filter((r) => r.end > r.start).sort((a, b) => a.start - b.start || a.end - b.end);
|
|
81
|
+
const out = [];
|
|
82
|
+
for (const range of sorted) {
|
|
83
|
+
const last = out[out.length - 1];
|
|
84
|
+
if (last !== undefined && range.start <= last.end)
|
|
85
|
+
last.end = Math.max(last.end, range.end);
|
|
86
|
+
else
|
|
87
|
+
out.push({ start: range.start, end: range.end });
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
/** Whether an offset lies in one of a list of merged, sorted ranges. */
|
|
92
|
+
export function inRanges(merged, offset) {
|
|
93
|
+
let low = 0;
|
|
94
|
+
let high = merged.length;
|
|
95
|
+
while (low < high) {
|
|
96
|
+
const mid = (low + high) >> 1;
|
|
97
|
+
const range = merged[mid];
|
|
98
|
+
if (offset < range.start)
|
|
99
|
+
high = mid;
|
|
100
|
+
else if (offset >= range.end)
|
|
101
|
+
low = mid + 1;
|
|
102
|
+
else
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const NOT_A_TERMINATOR = /[^\n\r]/g;
|
|
108
|
+
/**
|
|
109
|
+
* Blanks the given ranges with spaces, keeping every other character and
|
|
110
|
+
* every line terminator where it was.
|
|
111
|
+
*
|
|
112
|
+
* Offsets survive a mask, which is the point: something found at offset 400
|
|
113
|
+
* of the masked text is at offset 400 of the original, on the same line. The
|
|
114
|
+
* replacement walks UTF-16 code units, so a surrogate pair becomes two spaces
|
|
115
|
+
* and every later offset still lands where it did.
|
|
116
|
+
*/
|
|
117
|
+
export function maskRanges(text, ranges) {
|
|
118
|
+
const merged = mergeRanges(ranges);
|
|
119
|
+
if (merged.length === 0)
|
|
120
|
+
return text;
|
|
121
|
+
let out = '';
|
|
122
|
+
let cursor = 0;
|
|
123
|
+
for (const range of merged) {
|
|
124
|
+
const start = Math.min(range.start, text.length);
|
|
125
|
+
const end = Math.min(range.end, text.length);
|
|
126
|
+
out += text.slice(cursor, start);
|
|
127
|
+
out += text.slice(start, end).replace(NOT_A_TERMINATOR, ' ');
|
|
128
|
+
cursor = end;
|
|
129
|
+
}
|
|
130
|
+
return out + text.slice(cursor);
|
|
131
|
+
}
|
|
132
|
+
/** A text without a leading byte-order mark. */
|
|
133
|
+
export function stripBom(text) {
|
|
134
|
+
return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
|
|
135
|
+
}
|
|
136
|
+
/** The terminator a text mostly uses; `\n` when it has none or they tie. */
|
|
137
|
+
export function lineEnding(text) {
|
|
138
|
+
let crlf = 0;
|
|
139
|
+
let lf = 0;
|
|
140
|
+
for (let i = text.indexOf('\n'); i >= 0; i = text.indexOf('\n', i + 1)) {
|
|
141
|
+
if (i > 0 && text.charCodeAt(i - 1) === CR)
|
|
142
|
+
crlf += 1;
|
|
143
|
+
else
|
|
144
|
+
lf += 1;
|
|
145
|
+
}
|
|
146
|
+
return crlf > lf ? '\r\n' : '\n';
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The lines of a text, without terminators. Unlike the line table, a final
|
|
150
|
+
* terminator does produce a last, empty line, so that joining the lines with
|
|
151
|
+
* the same terminator gives the text back byte for byte.
|
|
152
|
+
*/
|
|
153
|
+
export function splitLines(text) {
|
|
154
|
+
return text.split(/\r\n|\n|\r/);
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../../../src/vendor/spec-core/text/lines.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lines, offsets and masks.\n *\n * Every finding a spec-* tool reports points at a line and a column, and every\n * structure the scanner builds carries raw offsets rather than copies of the\n * text. Converting between the two is on the hot path, so the line table is\n * built once per file and searched by bisection.\n *\n * All three line terminators end a line - `\\n`, `\\r\\n` and a lone `\\r`, as\n * CommonMark has it - and `\\r\\n` counts once. A Windows checkout of a document\n * must produce the line numbers a POSIX checkout does.\n */\n\nexport interface Position {\n /** UTF-16 offset into the text. */\n readonly offset: number;\n /** 1-based. */\n readonly line: number;\n /** 1-based, in UTF-16 code units. */\n readonly column: number;\n}\n\nexport interface LineIndex {\n /** Number of lines. A final terminator does not open a line of its own. */\n readonly lineCount: number;\n /** Offset at which a 1-based line starts. Out-of-range lines are clamped. */\n lineStart(line: number): number;\n /** Offset just past a 1-based line, before its terminator. */\n lineEnd(line: number): number;\n /** A 1-based line without its terminator. */\n lineText(line: number): string;\n /** The line and column of an offset. Out-of-range offsets are clamped. */\n positionAt(offset: number): Position;\n}\n\nconst LF = 10;\nconst CR = 13;\n\n/** Offsets at which each line starts; index 0 is line 1. */\nexport function lineStarts(text: string): number[] {\n const starts: number[] = [0];\n for (let i = 0; i < text.length; i += 1) {\n const ch = text.charCodeAt(i);\n if (ch === LF) {\n starts.push(i + 1);\n } else if (ch === CR) {\n if (text.charCodeAt(i + 1) === LF) i += 1;\n starts.push(i + 1);\n }\n }\n // A terminator at the very end opens a line that holds nothing; an editor\n // does not count it, and neither does this.\n if (starts.length > 1 && starts[starts.length - 1] === text.length) starts.pop();\n return starts;\n}\n\n/** Builds the line table for a text. */\nexport function createLineIndex(text: string): LineIndex {\n const starts = lineStarts(text);\n const lineCount = starts.length;\n const clamp = (line: number): number => (line < 1 ? 1 : line > lineCount ? lineCount : line);\n const startOf = (line: number): number => starts[clamp(line) - 1] as number;\n const endOf = (line: number): number => {\n const index = clamp(line);\n const start = starts[index - 1] as number;\n let end = index === lineCount ? text.length : (starts[index] as number);\n // At most two terminator characters, and never past the line's own start.\n if (end > start && text.charCodeAt(end - 1) === LF) end -= 1;\n if (end > start && text.charCodeAt(end - 1) === CR) end -= 1;\n return end;\n };\n return {\n lineCount,\n lineStart: startOf,\n lineEnd: endOf,\n lineText: (line) => text.slice(startOf(line), endOf(line)),\n positionAt: (offset) => locate(starts, offset < 0 ? 0 : offset > text.length ? text.length : offset),\n };\n}\n\n/**\n * The line and column of an offset, by bisection over a line table.\n *\n * The search is half-open: `high` is one past the last candidate, and it\n * narrows until one is left. There is no `- 1` to get wrong.\n */\nexport function locate(starts: readonly number[], offset: number): Position {\n let low = 0;\n let high = starts.length;\n while (high - low > 1) {\n const mid = (low + high) >> 1;\n if ((starts[mid] as number) <= offset) low = mid;\n else high = mid;\n }\n return { offset, line: low + 1, column: offset - (starts[low] as number) + 1 };\n}\n\n/** A half-open range of offsets. */\nexport interface Range {\n readonly start: number;\n readonly end: number;\n}\n\n/** Sorts and merges ranges; touching ranges merge. Empty ranges vanish. */\nexport function mergeRanges(ranges: readonly Range[]): Range[] {\n const sorted = ranges.filter((r) => r.end > r.start).sort((a, b) => a.start - b.start || a.end - b.end);\n const out: { start: number; end: number }[] = [];\n for (const range of sorted) {\n const last = out[out.length - 1];\n if (last !== undefined && range.start <= last.end) last.end = Math.max(last.end, range.end);\n else out.push({ start: range.start, end: range.end });\n }\n return out;\n}\n\n/** Whether an offset lies in one of a list of merged, sorted ranges. */\nexport function inRanges(merged: readonly Range[], offset: number): boolean {\n let low = 0;\n let high = merged.length;\n while (low < high) {\n const mid = (low + high) >> 1;\n const range = merged[mid] as Range;\n if (offset < range.start) high = mid;\n else if (offset >= range.end) low = mid + 1;\n else return true;\n }\n return false;\n}\n\nconst NOT_A_TERMINATOR = /[^\\n\\r]/g;\n\n/**\n * Blanks the given ranges with spaces, keeping every other character and\n * every line terminator where it was.\n *\n * Offsets survive a mask, which is the point: something found at offset 400\n * of the masked text is at offset 400 of the original, on the same line. The\n * replacement walks UTF-16 code units, so a surrogate pair becomes two spaces\n * and every later offset still lands where it did.\n */\nexport function maskRanges(text: string, ranges: readonly Range[]): string {\n const merged = mergeRanges(ranges);\n if (merged.length === 0) return text;\n let out = '';\n let cursor = 0;\n for (const range of merged) {\n const start = Math.min(range.start, text.length);\n const end = Math.min(range.end, text.length);\n out += text.slice(cursor, start);\n out += text.slice(start, end).replace(NOT_A_TERMINATOR, ' ');\n cursor = end;\n }\n return out + text.slice(cursor);\n}\n\n/** A text without a leading byte-order mark. */\nexport function stripBom(text: string): string {\n return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n}\n\n/** The terminator a text mostly uses; `\\n` when it has none or they tie. */\nexport function lineEnding(text: string): '\\n' | '\\r\\n' {\n let crlf = 0;\n let lf = 0;\n for (let i = text.indexOf('\\n'); i >= 0; i = text.indexOf('\\n', i + 1)) {\n if (i > 0 && text.charCodeAt(i - 1) === CR) crlf += 1;\n else lf += 1;\n }\n return crlf > lf ? '\\r\\n' : '\\n';\n}\n\n/**\n * The lines of a text, without terminators. Unlike the line table, a final\n * terminator does produce a last, empty line, so that joining the lines with\n * the same terminator gives the text back byte for byte.\n */\nexport function splitLines(text: string): string[] {\n return text.split(/\\r\\n|\\n|\\r/);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@descent-vtt/spec-brief",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Lifecycle management for task briefs: lint the contract, map parallel collisions, and archive a round in one atomic command.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"README.md",
|
|
39
39
|
"bin",
|
|
40
40
|
"dist",
|
|
41
|
-
"schema.json"
|
|
41
|
+
"schema.json",
|
|
42
|
+
"src/vendor/spec-core/LICENSE"
|
|
42
43
|
],
|
|
43
44
|
"publishConfig": {
|
|
44
45
|
"access": "public"
|
|
@@ -54,7 +55,7 @@
|
|
|
54
55
|
"test:mutation:full": "stryker run",
|
|
55
56
|
"schema": "npm run build && node scripts/write-schema.mjs",
|
|
56
57
|
"selfcheck": "node ./bin/spec-brief.js lint",
|
|
57
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
58
|
+
"prepublishOnly": "node -e \"if (process.env.GITHUB_ACTIONS !== 'true') { console.error('npm publish is refused outside GitHub Actions: a release is a v* tag, staged by CI with provenance.'); process.exit(1) }\" && npm run clean && npm run build"
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {},
|
|
60
61
|
"devDependencies": {
|
package/schema.json
CHANGED
|
@@ -84,6 +84,13 @@
|
|
|
84
84
|
"type": "string",
|
|
85
85
|
"minLength": 1
|
|
86
86
|
},
|
|
87
|
+
"deferred": {
|
|
88
|
+
"description": "The word for a live brief put off until the event its \"trigger\" names, or null. A deferred brief is never ready and runs in no wave.",
|
|
89
|
+
"type": [
|
|
90
|
+
"string",
|
|
91
|
+
"null"
|
|
92
|
+
]
|
|
93
|
+
},
|
|
87
94
|
"archived": {
|
|
88
95
|
"description": "The word for an archived brief.",
|
|
89
96
|
"type": "string",
|
|
@@ -133,6 +140,11 @@
|
|
|
133
140
|
"optional": {
|
|
134
141
|
"description": "Checked when present, not required.",
|
|
135
142
|
"type": "boolean"
|
|
143
|
+
},
|
|
144
|
+
"hint": {
|
|
145
|
+
"description": "What the section must answer: a comment under the heading in a new brief, and the hint of a finding that it is missing or unwritten.",
|
|
146
|
+
"type": "string",
|
|
147
|
+
"minLength": 1
|
|
136
148
|
}
|
|
137
149
|
},
|
|
138
150
|
"additionalProperties": false,
|
|
@@ -193,6 +205,11 @@
|
|
|
193
205
|
"optional": {
|
|
194
206
|
"description": "Checked when present, not required.",
|
|
195
207
|
"type": "boolean"
|
|
208
|
+
},
|
|
209
|
+
"hint": {
|
|
210
|
+
"description": "What the section must answer: a comment under the heading in a new brief, and the hint of a finding that it is missing or unwritten.",
|
|
211
|
+
"type": "string",
|
|
212
|
+
"minLength": 1
|
|
196
213
|
}
|
|
197
214
|
},
|
|
198
215
|
"additionalProperties": false,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 spec-core contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Vendored from spec-core
|
|
2
|
+
|
|
3
|
+
These files are copies of modules from
|
|
4
|
+
[spec-core](https://github.com/DescentVTT/spec-core), byte for byte. Do not edit them here: change
|
|
5
|
+
spec-core, then run `node scripts/vendor.mjs --into <this tool>` there.
|
|
6
|
+
`VENDOR.json` records the commit and the SHA-256 of every file, and this
|
|
7
|
+
tool's tests fail when a file no longer matches its hash. `LICENSE` is
|
|
8
|
+
spec-core's, and ships in this tool's package with the compiled copies.
|