@agentshouse/mdmodel 0.1.0-alpha.10 → 0.1.0-alpha.11

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/README.md CHANGED
@@ -225,12 +225,17 @@ if (parsed.ok) {
225
225
 
226
226
  `DivisionContext` is a `ProjectionContext` and one `budget`, the greatest number
227
227
  of characters a Span's embedded text may carry, counted the way JavaScript
228
- counts a string's length and not in the bytes the extent is measured in. A
229
- bound cut inside one sentence carries a character whole rather than dividing
230
- it, so such a Span may run one unit past the budget. The budget is the caller's
231
- number alone: the model holds no tokenizer, counts nothing else, and refuses no
232
- input for being too long. A Document the caller supplies no definition for
233
- carries the same `unknown-type` refusal `project` returns.
228
+ counts a string's length and not in the bytes the extent is measured in. No
229
+ Span's text is ever longer than the budget. A bound cut never divides a
230
+ character: where the budget ends between the two halves of a surrogate pair,
231
+ the cut falls before the pair. A cut never falls inside link syntax either: it
232
+ falls before an internal link, and a label longer than a whole piece's room is
233
+ divided at the bound like any other text. The smallest budget is `2`, the
234
+ length of one astral character; a budget that is not a whole number of at least
235
+ `2` is refused with `division-budget` before any division. The budget is the
236
+ caller's number alone: the model holds no tokenizer, counts nothing else, and
237
+ refuses no input for being too long. A Document the caller supplies no
238
+ definition for carries the same `unknown-type` refusal `project` returns.
234
239
 
235
240
  The division descends one level at a time, and only into the piece that does not
236
241
  fit: the whole input, a heading node, adjacent sibling nodes packed under one
@@ -241,8 +246,10 @@ continues a node repeats that node's own heading line, projected like any other
241
246
  text and so carrying an internal link's label rather than its destination, and
242
247
  never an ancestor's heading, so renaming a heading costs what editing that
243
248
  heading's own body costs. A heading the budget cannot hold beside any text is
244
- not repeated, and a heading with no body of its own leads its first child node
245
- rather than standing as a Span of nothing but itself. Overlap exists at the
249
+ not repeated, a continuation piece that begins with an astral character the
250
+ room beside its heading cannot hold is carried without the heading, and a
251
+ heading with no body of its own leads its first child node rather than standing
252
+ as a Span of nothing but itself. Overlap exists at the
246
253
  sentence level alone, where each Span after the first repeats its predecessor's
247
254
  last sentence whenever the budget holds both; when it cannot hold both, the
248
255
  Span carries its own sentence alone. An untyped input arrives without a
@@ -1 +1 @@
1
- {"version":3,"file":"divide.d.ts","sourceRoot":"","sources":["../src/divide.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAgB,MAAM,YAAY,CAAC;AAoWpF,wBAAgB,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,QAAQ,CAW3F"}
1
+ {"version":3,"file":"divide.d.ts","sourceRoot":"","sources":["../src/divide.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAgB,MAAM,YAAY,CAAC;AA4WpF,wBAAgB,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,QAAQ,CAc3F"}
package/dist/divide.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { blockRanges, headingLines } from './blocks.js';
2
2
  import { projectionInput, rangeText } from './project.js';
3
+ import { refusal } from './refuse.js';
4
+ const SMALLEST_BUDGET = 2;
3
5
  function node(draft) {
4
6
  return {
5
7
  start: draft.start,
@@ -98,15 +100,18 @@ function isTrailingSurrogate(text, index) {
98
100
  const code = text.charCodeAt(index);
99
101
  return code >= 0xdc00 && code <= 0xdfff;
100
102
  }
103
+ function characterLength(text, index) {
104
+ return isTrailingSurrogate(text, index + 1) ? 2 : 1;
105
+ }
101
106
  function boundOf(cutting, from, to, budget) {
102
- const limit = from + Math.max(budget, 1);
107
+ const limit = from + budget;
103
108
  if (limit >= to) return to;
104
109
  for(let index = limit; index > from + 1; index -= 1){
105
110
  if (isSpace(cutting.text[index])) return index;
106
111
  }
107
112
  const inside = cutting.masks.find((mask)=>limit > mask.start && limit < mask.end);
108
113
  if (inside !== undefined) return inside.start > from ? inside.start : Math.min(inside.end, to);
109
- return isTrailingSurrogate(cutting.text, limit) ? limit + 1 : limit;
114
+ return isTrailingSurrogate(cutting.text, limit) ? limit - 1 : limit;
110
115
  }
111
116
  function utf8Size(code) {
112
117
  if (code < 0x80) return 1;
@@ -187,9 +192,9 @@ function prefixOf(state, body) {
187
192
  function available(state, body) {
188
193
  return state.budget - prefixOf(state, body).length;
189
194
  }
190
- function emit(state, body, piece) {
195
+ function emit(state, body, piece, bare = false) {
191
196
  if (piece.text.trim() === '') return;
192
- const text = prefixOf(state, body) + piece.text;
197
+ const text = (bare ? '' : prefixOf(state, body)) + piece.text;
193
198
  state.spans.push({
194
199
  start: piece.start,
195
200
  end: piece.end,
@@ -228,10 +233,12 @@ function divideUnits(state, body, units) {
228
233
  function divideBound(state, body, cutting, range) {
229
234
  let start = range.start;
230
235
  while(start < range.end){
231
- const stop = boundOf(cutting, start, range.end, available(state, body));
236
+ const bare = available(state, body) < characterLength(cutting.text, start);
237
+ const room = bare ? state.budget : available(state, body);
238
+ const stop = boundOf(cutting, start, range.end, room);
232
239
  const piece = cutting.piece(start, stop);
233
- if (cutting.masks.length === 0 || piece.text.length <= available(state, body)) {
234
- emit(state, body, piece);
240
+ if (cutting.masks.length === 0 || piece.text.length <= room) {
241
+ emit(state, body, piece, bare);
235
242
  } else {
236
243
  divideBound(state, body, valueCutting(piece), {
237
244
  start: 0,
@@ -342,6 +349,12 @@ function divideInput(state, input) {
342
349
  ]);
343
350
  }
344
351
  export function divide(document, file, context) {
352
+ if (!Number.isInteger(context.budget) || context.budget < SMALLEST_BUDGET) {
353
+ return {
354
+ ok: false,
355
+ refusal: refusal(file, 'division-budget')
356
+ };
357
+ }
345
358
  const result = projectionInput(document, file, context);
346
359
  if (!result.ok) return {
347
360
  ok: false,
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdmodel/src/divide.ts"],"sourcesContent":["import { blockRanges, headingLines } from './blocks.js';\nimport { projectionInput, rangeText, type Edit, type Input, type Piece } from './project.js';\nimport type { Division, DivisionContext, Document, Extent, Span } from './types.js';\n\ntype Node = {\n readonly start: number;\n readonly end: number;\n readonly bodyStart: number;\n readonly heading: string;\n readonly children: readonly Node[];\n};\n\ntype Draft = {\n readonly level: number;\n start: number;\n end: number;\n readonly bodyStart: number;\n readonly heading: string;\n readonly children: Draft[];\n};\n\ntype State = {\n readonly content: string;\n readonly edits: readonly Edit[];\n readonly budget: number;\n readonly spans: Span[];\n};\n\ntype Body = {\n readonly heading: string;\n emitted: number;\n};\n\ntype Unit = Piece & { readonly descend: () => void };\n\ntype Cutting = {\n readonly text: string;\n readonly masks: readonly Extent[];\n readonly piece: (from: number, to: number) => Piece;\n};\n\nfunction node(draft: Draft): Node {\n return {\n start: draft.start,\n end: draft.end,\n bodyStart: draft.bodyStart,\n heading: draft.heading,\n children: draft.children.map(node),\n };\n}\n\nfunction forest(state: State, range: Extent): Node[] {\n const content = state.content;\n const headings = headingLines(content, range.start, range.end);\n const roots: Draft[] = [];\n const open: Draft[] = [];\n const first = headings[0]?.start ?? range.end;\n if (first > range.start) {\n roots.push({\n level: 0,\n start: range.start,\n end: first,\n bodyStart: range.start,\n heading: '',\n children: [],\n });\n }\n for (const heading of headings) {\n while ((open[open.length - 1]?.level ?? 0) >= heading.level) {\n open.pop()!.end = heading.start;\n }\n const draft: Draft = {\n level: heading.level,\n start: heading.start,\n end: range.end,\n bodyStart: heading.next,\n heading: `${textOf(state, { start: heading.start, end: heading.textEnd })}\\n\\n`,\n children: [],\n };\n (open[open.length - 1]?.children ?? roots).push(draft);\n open.push(draft);\n }\n return roots.map(node);\n}\n\nfunction isSpace(character: string): boolean {\n return character === ' ' || character === '\\t' || character === '\\n' || character === '\\r';\n}\n\nconst TERMINATORS = new Set(['.', '!', '?', '…', '。', '!', '?']);\n\nfunction isTerminator(character: string): boolean {\n return TERMINATORS.has(character);\n}\n\nconst CLOSERS = new Set(['\"', \"'\", ')', ']', '»', '”']);\n\nfunction isCloser(character: string): boolean {\n return CLOSERS.has(character);\n}\n\nfunction sentenceBounds(text: string): number[] {\n const bounds = [0];\n let i = 0;\n while (i < text.length) {\n if (!isTerminator(text[i]!)) {\n i += 1;\n continue;\n }\n let after = i + 1;\n while (after < text.length && isCloser(text[after]!)) after += 1;\n if (after >= text.length || !isSpace(text[after]!)) {\n i = after + 1;\n continue;\n }\n while (after < text.length && isSpace(text[after]!)) after += 1;\n if (after < text.length) bounds.push(after);\n i = after;\n }\n bounds.push(text.length);\n return bounds;\n}\n\nfunction isTrailingSurrogate(text: string, index: number): boolean {\n const code = text.charCodeAt(index);\n return code >= 0xdc00 && code <= 0xdfff;\n}\n\nfunction boundOf(cutting: Cutting, from: number, to: number, budget: number): number {\n const limit = from + Math.max(budget, 1);\n if (limit >= to) return to;\n for (let index = limit; index > from + 1; index -= 1) {\n if (isSpace(cutting.text[index]!)) return index;\n }\n const inside = cutting.masks.find((mask) => limit > mask.start && limit < mask.end);\n if (inside !== undefined) return inside.start > from ? inside.start : Math.min(inside.end, to);\n return isTrailingSurrogate(cutting.text, limit) ? limit + 1 : limit;\n}\n\nfunction utf8Size(code: number): number {\n if (code < 0x80) return 1;\n if (code < 0x800) return 2;\n if (code < 0x10000) return 3;\n return 4;\n}\n\nfunction byteBounds(content: string, spans: readonly Span[]): Span[] {\n const marks = [...new Set(spans.flatMap((span) => [span.start, span.end]))].sort(\n (left, right) => left - right,\n );\n const bytes = new Map<number, number>();\n let index = 0;\n let count = 0;\n for (const mark of marks) {\n while (index < mark) {\n const code = content.codePointAt(index)!;\n count += utf8Size(code);\n index += code > 0xffff ? 2 : 1;\n }\n bytes.set(mark, count);\n }\n return spans.map((span) => ({\n ...span,\n start: bytes.get(span.start)!,\n end: bytes.get(span.end)!,\n }));\n}\n\nfunction textOf(state: State, extent: Extent): string {\n return rangeText(state.content, extent, state.edits);\n}\n\nfunction sourceCutting(state: State, extent: Extent): Cutting {\n let text = state.content.slice(extent.start, extent.end);\n const masks: Extent[] = [];\n for (const edit of state.edits) {\n if (edit.start < extent.start || edit.end > extent.end) continue;\n const from = edit.start - extent.start;\n const to = edit.end - extent.start;\n text = `${text.slice(0, from)}${'x'.repeat(to - from)}${text.slice(to)}`;\n masks.push({ start: from, end: to });\n }\n return {\n text,\n masks,\n piece: (from, to) => {\n const cut = { start: extent.start + from, end: extent.start + to };\n return { ...cut, text: textOf(state, cut) };\n },\n };\n}\n\nfunction valueCutting(value: Piece): Cutting {\n return {\n text: value.text,\n masks: [],\n piece: (from, to) => ({ start: value.start, end: value.end, text: value.text.slice(from, to) }),\n };\n}\n\nfunction prefixOf(state: State, body: Body): string {\n if (body.emitted === 0 || body.heading.length >= state.budget) return '';\n return body.heading;\n}\n\nfunction available(state: State, body: Body): number {\n return state.budget - prefixOf(state, body).length;\n}\n\nfunction emit(state: State, body: Body, piece: Piece): void {\n if (piece.text.trim() === '') return;\n const text = prefixOf(state, body) + piece.text;\n state.spans.push({ start: piece.start, end: piece.end, text });\n body.emitted += 1;\n}\n\nfunction merge(run: readonly Unit[]): Piece {\n return {\n start: Math.min(...run.map((unit) => unit.start)),\n end: Math.max(...run.map((unit) => unit.end)),\n text: run.map((unit) => unit.text).join(''),\n };\n}\n\nfunction divideUnits(state: State, body: Body, units: readonly Unit[]): void {\n let run: Unit[] = [];\n let length = 0;\n const flush = (): void => {\n if (run.length === 0) return;\n emit(state, body, merge(run));\n run = [];\n length = 0;\n };\n for (const unit of units) {\n if (run.length > 0 && length + unit.text.length > available(state, body)) flush();\n if (unit.text.length > available(state, body)) {\n flush();\n unit.descend();\n continue;\n }\n run.push(unit);\n length += unit.text.length;\n }\n flush();\n}\n\nfunction divideBound(state: State, body: Body, cutting: Cutting, range: Extent): void {\n let start = range.start;\n while (start < range.end) {\n const stop = boundOf(cutting, start, range.end, available(state, body));\n const piece = cutting.piece(start, stop);\n if (cutting.masks.length === 0 || piece.text.length <= available(state, body)) {\n emit(state, body, piece);\n } else {\n divideBound(state, body, valueCutting(piece), { start: 0, end: piece.text.length });\n }\n start = stop;\n }\n}\n\nfunction divideSentences(state: State, body: Body, cutting: Cutting): void {\n const cut = cutting.piece;\n const bounds = sentenceBounds(cutting.text);\n let index = 0;\n while (index + 1 < bounds.length) {\n const alone = { start: bounds[index]!, end: bounds[index + 1]! };\n if (cut(alone.start, alone.end).text.length > available(state, body)) {\n divideBound(state, body, cutting, alone);\n index += 1;\n continue;\n }\n const carried = bounds[Math.max(index - 1, 0)]!;\n const from =\n cut(carried, alone.end).text.length <= available(state, body) ? carried : alone.start;\n let last = index;\n while (\n last + 2 < bounds.length &&\n cut(from, bounds[last + 2]!).text.length <= available(state, body)\n ) {\n last += 1;\n }\n emit(state, body, cut(from, bounds[last + 1]!));\n index = last + 1;\n }\n}\n\nfunction blockUnit(state: State, body: Body, block: Extent): Unit {\n return {\n start: block.start,\n end: block.end,\n text: textOf(state, block),\n descend: () => divideSentences(state, body, sourceCutting(state, block)),\n };\n}\n\nfunction valueUnit(state: State, body: Body, value: Piece): Unit {\n return {\n start: value.start,\n end: value.end,\n text: value.text,\n descend: () => divideSentences(state, body, valueCutting(value)),\n };\n}\n\nfunction nodeUnit(state: State, subject: Node): Unit {\n return {\n start: subject.start,\n end: subject.end,\n text: textOf(state, subject),\n descend: () => divideNode(state, subject),\n };\n}\n\nfunction ownBlocks(subject: Node, end: number, blocks: readonly Extent[]): Extent[] {\n const first = blocks[0];\n return first === undefined\n ? [{ start: subject.start, end }]\n : [{ start: subject.start, end: first.end }, ...blocks.slice(1)];\n}\n\nfunction divideNode(state: State, subject: Node): void {\n const end = subject.children[0]?.start ?? subject.end;\n const blocks = blockRanges(state.content, subject.bodyStart, end);\n const children: Body = { heading: '', emitted: 0 };\n if (blocks.length === 0 && subject.children.length > 0) {\n const [first, ...rest] = subject.children;\n const led = [{ ...first!, start: subject.start }, ...rest];\n divideUnits(\n state,\n children,\n led.map((child) => nodeUnit(state, child)),\n );\n return;\n }\n const body: Body = { heading: subject.heading, emitted: 0 };\n const own = ownBlocks(subject, end, blocks);\n divideUnits(\n state,\n body,\n own.map((block) => blockUnit(state, body, block)),\n );\n divideUnits(\n state,\n children,\n subject.children.map((child) => nodeUnit(state, child)),\n );\n}\n\nfunction divideInput(state: State, input: Input): void {\n const body: Body = { heading: '', emitted: 0 };\n divideUnits(state, body, [\n ...input.values.map((value) => valueUnit(state, body, value)),\n ...input.ranges.flatMap((range) =>\n forest(state, range).map((subject) => nodeUnit(state, subject)),\n ),\n ]);\n}\n\nexport function divide(document: Document, file: string, context: DivisionContext): Division {\n const result = projectionInput(document, file, context);\n if (!result.ok) return { ok: false, refusal: result.refusal };\n const state: State = {\n content: document.content,\n edits: result.input.edits,\n budget: context.budget,\n spans: [],\n };\n divideInput(state, result.input);\n return { ok: true, spans: byteBounds(document.content, state.spans) };\n}\n"],"names":["blockRanges","headingLines","projectionInput","rangeText","node","draft","start","end","bodyStart","heading","children","map","forest","state","range","content","headings","roots","open","first","push","level","length","pop","next","textOf","textEnd","isSpace","character","TERMINATORS","Set","isTerminator","has","CLOSERS","isCloser","sentenceBounds","text","bounds","i","after","isTrailingSurrogate","index","code","charCodeAt","boundOf","cutting","from","to","budget","limit","Math","max","inside","masks","find","mask","undefined","min","utf8Size","byteBounds","spans","marks","flatMap","span","sort","left","right","bytes","Map","count","mark","codePointAt","set","get","extent","edits","sourceCutting","slice","edit","repeat","piece","cut","valueCutting","value","prefixOf","body","emitted","available","emit","trim","merge","run","unit","join","divideUnits","units","flush","descend","divideBound","stop","divideSentences","alone","carried","last","blockUnit","block","valueUnit","nodeUnit","subject","divideNode","ownBlocks","blocks","rest","led","child","own","divideInput","input","values","ranges","divide","document","file","context","result","ok","refusal"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdmodel/src/divide.ts"],"sourcesContent":["import { blockRanges, headingLines } from './blocks.js';\nimport { projectionInput, rangeText, type Edit, type Input, type Piece } from './project.js';\nimport { refusal } from './refuse.js';\nimport type { Division, DivisionContext, Document, Extent, Span } from './types.js';\n\nconst SMALLEST_BUDGET = 2;\n\ntype Node = {\n readonly start: number;\n readonly end: number;\n readonly bodyStart: number;\n readonly heading: string;\n readonly children: readonly Node[];\n};\n\ntype Draft = {\n readonly level: number;\n start: number;\n end: number;\n readonly bodyStart: number;\n readonly heading: string;\n readonly children: Draft[];\n};\n\ntype State = {\n readonly content: string;\n readonly edits: readonly Edit[];\n readonly budget: number;\n readonly spans: Span[];\n};\n\ntype Body = {\n readonly heading: string;\n emitted: number;\n};\n\ntype Unit = Piece & { readonly descend: () => void };\n\ntype Cutting = {\n readonly text: string;\n readonly masks: readonly Extent[];\n readonly piece: (from: number, to: number) => Piece;\n};\n\nfunction node(draft: Draft): Node {\n return {\n start: draft.start,\n end: draft.end,\n bodyStart: draft.bodyStart,\n heading: draft.heading,\n children: draft.children.map(node),\n };\n}\n\nfunction forest(state: State, range: Extent): Node[] {\n const content = state.content;\n const headings = headingLines(content, range.start, range.end);\n const roots: Draft[] = [];\n const open: Draft[] = [];\n const first = headings[0]?.start ?? range.end;\n if (first > range.start) {\n roots.push({\n level: 0,\n start: range.start,\n end: first,\n bodyStart: range.start,\n heading: '',\n children: [],\n });\n }\n for (const heading of headings) {\n while ((open[open.length - 1]?.level ?? 0) >= heading.level) {\n open.pop()!.end = heading.start;\n }\n const draft: Draft = {\n level: heading.level,\n start: heading.start,\n end: range.end,\n bodyStart: heading.next,\n heading: `${textOf(state, { start: heading.start, end: heading.textEnd })}\\n\\n`,\n children: [],\n };\n (open[open.length - 1]?.children ?? roots).push(draft);\n open.push(draft);\n }\n return roots.map(node);\n}\n\nfunction isSpace(character: string): boolean {\n return character === ' ' || character === '\\t' || character === '\\n' || character === '\\r';\n}\n\nconst TERMINATORS = new Set(['.', '!', '?', '…', '。', '!', '?']);\n\nfunction isTerminator(character: string): boolean {\n return TERMINATORS.has(character);\n}\n\nconst CLOSERS = new Set(['\"', \"'\", ')', ']', '»', '”']);\n\nfunction isCloser(character: string): boolean {\n return CLOSERS.has(character);\n}\n\nfunction sentenceBounds(text: string): number[] {\n const bounds = [0];\n let i = 0;\n while (i < text.length) {\n if (!isTerminator(text[i]!)) {\n i += 1;\n continue;\n }\n let after = i + 1;\n while (after < text.length && isCloser(text[after]!)) after += 1;\n if (after >= text.length || !isSpace(text[after]!)) {\n i = after + 1;\n continue;\n }\n while (after < text.length && isSpace(text[after]!)) after += 1;\n if (after < text.length) bounds.push(after);\n i = after;\n }\n bounds.push(text.length);\n return bounds;\n}\n\nfunction isTrailingSurrogate(text: string, index: number): boolean {\n const code = text.charCodeAt(index);\n return code >= 0xdc00 && code <= 0xdfff;\n}\n\nfunction characterLength(text: string, index: number): number {\n return isTrailingSurrogate(text, index + 1) ? 2 : 1;\n}\n\nfunction boundOf(cutting: Cutting, from: number, to: number, budget: number): number {\n const limit = from + budget;\n if (limit >= to) return to;\n for (let index = limit; index > from + 1; index -= 1) {\n if (isSpace(cutting.text[index]!)) return index;\n }\n const inside = cutting.masks.find((mask) => limit > mask.start && limit < mask.end);\n if (inside !== undefined) return inside.start > from ? inside.start : Math.min(inside.end, to);\n return isTrailingSurrogate(cutting.text, limit) ? limit - 1 : limit;\n}\n\nfunction utf8Size(code: number): number {\n if (code < 0x80) return 1;\n if (code < 0x800) return 2;\n if (code < 0x10000) return 3;\n return 4;\n}\n\nfunction byteBounds(content: string, spans: readonly Span[]): Span[] {\n const marks = [...new Set(spans.flatMap((span) => [span.start, span.end]))].sort(\n (left, right) => left - right,\n );\n const bytes = new Map<number, number>();\n let index = 0;\n let count = 0;\n for (const mark of marks) {\n while (index < mark) {\n const code = content.codePointAt(index)!;\n count += utf8Size(code);\n index += code > 0xffff ? 2 : 1;\n }\n bytes.set(mark, count);\n }\n return spans.map((span) => ({\n ...span,\n start: bytes.get(span.start)!,\n end: bytes.get(span.end)!,\n }));\n}\n\nfunction textOf(state: State, extent: Extent): string {\n return rangeText(state.content, extent, state.edits);\n}\n\nfunction sourceCutting(state: State, extent: Extent): Cutting {\n let text = state.content.slice(extent.start, extent.end);\n const masks: Extent[] = [];\n for (const edit of state.edits) {\n if (edit.start < extent.start || edit.end > extent.end) continue;\n const from = edit.start - extent.start;\n const to = edit.end - extent.start;\n text = `${text.slice(0, from)}${'x'.repeat(to - from)}${text.slice(to)}`;\n masks.push({ start: from, end: to });\n }\n return {\n text,\n masks,\n piece: (from, to) => {\n const cut = { start: extent.start + from, end: extent.start + to };\n return { ...cut, text: textOf(state, cut) };\n },\n };\n}\n\nfunction valueCutting(value: Piece): Cutting {\n return {\n text: value.text,\n masks: [],\n piece: (from, to) => ({ start: value.start, end: value.end, text: value.text.slice(from, to) }),\n };\n}\n\nfunction prefixOf(state: State, body: Body): string {\n if (body.emitted === 0 || body.heading.length >= state.budget) return '';\n return body.heading;\n}\n\nfunction available(state: State, body: Body): number {\n return state.budget - prefixOf(state, body).length;\n}\n\nfunction emit(state: State, body: Body, piece: Piece, bare = false): void {\n if (piece.text.trim() === '') return;\n const text = (bare ? '' : prefixOf(state, body)) + piece.text;\n state.spans.push({ start: piece.start, end: piece.end, text });\n body.emitted += 1;\n}\n\nfunction merge(run: readonly Unit[]): Piece {\n return {\n start: Math.min(...run.map((unit) => unit.start)),\n end: Math.max(...run.map((unit) => unit.end)),\n text: run.map((unit) => unit.text).join(''),\n };\n}\n\nfunction divideUnits(state: State, body: Body, units: readonly Unit[]): void {\n let run: Unit[] = [];\n let length = 0;\n const flush = (): void => {\n if (run.length === 0) return;\n emit(state, body, merge(run));\n run = [];\n length = 0;\n };\n for (const unit of units) {\n if (run.length > 0 && length + unit.text.length > available(state, body)) flush();\n if (unit.text.length > available(state, body)) {\n flush();\n unit.descend();\n continue;\n }\n run.push(unit);\n length += unit.text.length;\n }\n flush();\n}\n\nfunction divideBound(state: State, body: Body, cutting: Cutting, range: Extent): void {\n let start = range.start;\n while (start < range.end) {\n const bare = available(state, body) < characterLength(cutting.text, start);\n const room = bare ? state.budget : available(state, body);\n const stop = boundOf(cutting, start, range.end, room);\n const piece = cutting.piece(start, stop);\n if (cutting.masks.length === 0 || piece.text.length <= room) {\n emit(state, body, piece, bare);\n } else {\n divideBound(state, body, valueCutting(piece), { start: 0, end: piece.text.length });\n }\n start = stop;\n }\n}\n\nfunction divideSentences(state: State, body: Body, cutting: Cutting): void {\n const cut = cutting.piece;\n const bounds = sentenceBounds(cutting.text);\n let index = 0;\n while (index + 1 < bounds.length) {\n const alone = { start: bounds[index]!, end: bounds[index + 1]! };\n if (cut(alone.start, alone.end).text.length > available(state, body)) {\n divideBound(state, body, cutting, alone);\n index += 1;\n continue;\n }\n const carried = bounds[Math.max(index - 1, 0)]!;\n const from =\n cut(carried, alone.end).text.length <= available(state, body) ? carried : alone.start;\n let last = index;\n while (\n last + 2 < bounds.length &&\n cut(from, bounds[last + 2]!).text.length <= available(state, body)\n ) {\n last += 1;\n }\n emit(state, body, cut(from, bounds[last + 1]!));\n index = last + 1;\n }\n}\n\nfunction blockUnit(state: State, body: Body, block: Extent): Unit {\n return {\n start: block.start,\n end: block.end,\n text: textOf(state, block),\n descend: () => divideSentences(state, body, sourceCutting(state, block)),\n };\n}\n\nfunction valueUnit(state: State, body: Body, value: Piece): Unit {\n return {\n start: value.start,\n end: value.end,\n text: value.text,\n descend: () => divideSentences(state, body, valueCutting(value)),\n };\n}\n\nfunction nodeUnit(state: State, subject: Node): Unit {\n return {\n start: subject.start,\n end: subject.end,\n text: textOf(state, subject),\n descend: () => divideNode(state, subject),\n };\n}\n\nfunction ownBlocks(subject: Node, end: number, blocks: readonly Extent[]): Extent[] {\n const first = blocks[0];\n return first === undefined\n ? [{ start: subject.start, end }]\n : [{ start: subject.start, end: first.end }, ...blocks.slice(1)];\n}\n\nfunction divideNode(state: State, subject: Node): void {\n const end = subject.children[0]?.start ?? subject.end;\n const blocks = blockRanges(state.content, subject.bodyStart, end);\n const children: Body = { heading: '', emitted: 0 };\n if (blocks.length === 0 && subject.children.length > 0) {\n const [first, ...rest] = subject.children;\n const led = [{ ...first!, start: subject.start }, ...rest];\n divideUnits(\n state,\n children,\n led.map((child) => nodeUnit(state, child)),\n );\n return;\n }\n const body: Body = { heading: subject.heading, emitted: 0 };\n const own = ownBlocks(subject, end, blocks);\n divideUnits(\n state,\n body,\n own.map((block) => blockUnit(state, body, block)),\n );\n divideUnits(\n state,\n children,\n subject.children.map((child) => nodeUnit(state, child)),\n );\n}\n\nfunction divideInput(state: State, input: Input): void {\n const body: Body = { heading: '', emitted: 0 };\n divideUnits(state, body, [\n ...input.values.map((value) => valueUnit(state, body, value)),\n ...input.ranges.flatMap((range) =>\n forest(state, range).map((subject) => nodeUnit(state, subject)),\n ),\n ]);\n}\n\nexport function divide(document: Document, file: string, context: DivisionContext): Division {\n if (!Number.isInteger(context.budget) || context.budget < SMALLEST_BUDGET) {\n return { ok: false, refusal: refusal(file, 'division-budget') };\n }\n const result = projectionInput(document, file, context);\n if (!result.ok) return { ok: false, refusal: result.refusal };\n const state: State = {\n content: document.content,\n edits: result.input.edits,\n budget: context.budget,\n spans: [],\n };\n divideInput(state, result.input);\n return { ok: true, spans: byteBounds(document.content, state.spans) };\n}\n"],"names":["blockRanges","headingLines","projectionInput","rangeText","refusal","SMALLEST_BUDGET","node","draft","start","end","bodyStart","heading","children","map","forest","state","range","content","headings","roots","open","first","push","level","length","pop","next","textOf","textEnd","isSpace","character","TERMINATORS","Set","isTerminator","has","CLOSERS","isCloser","sentenceBounds","text","bounds","i","after","isTrailingSurrogate","index","code","charCodeAt","characterLength","boundOf","cutting","from","to","budget","limit","inside","masks","find","mask","undefined","Math","min","utf8Size","byteBounds","spans","marks","flatMap","span","sort","left","right","bytes","Map","count","mark","codePointAt","set","get","extent","edits","sourceCutting","slice","edit","repeat","piece","cut","valueCutting","value","prefixOf","body","emitted","available","emit","bare","trim","merge","run","unit","max","join","divideUnits","units","flush","descend","divideBound","room","stop","divideSentences","alone","carried","last","blockUnit","block","valueUnit","nodeUnit","subject","divideNode","ownBlocks","blocks","rest","led","child","own","divideInput","input","values","ranges","divide","document","file","context","Number","isInteger","ok","result"],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.0-alpha.10";
1
+ export declare const VERSION = "0.1.0-alpha.11";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
- export const VERSION = '0.1.0-alpha.10';
1
+ export const VERSION = '0.1.0-alpha.11';
2
2
 
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdmodel/src/version.ts"],"sourcesContent":["export const VERSION = '0.1.0-alpha.10';\n"],"names":["VERSION"],"mappings":"AAAA,OAAO,MAAMA,UAAU,iBAAiB"}
1
+ {"version":3,"sources":["/workspace/packages/mdmodel/src/version.ts"],"sourcesContent":["export const VERSION = '0.1.0-alpha.11';\n"],"names":["VERSION"],"mappings":"AAAA,OAAO,MAAMA,UAAU,iBAAiB"}
@@ -113,9 +113,10 @@ replace it with the package's semantic version before comparing.
113
113
  | `structured-section` | A declared structured-list section does not parse as a list |
114
114
  | `referenced-missing-file` | Remaining files still reference an absent path |
115
115
  | `unwritable-link` | No Markdown destination form can carry a new link destination |
116
+ | `division-budget` | A division budget is not a whole number of at least 2 |
116
117
 
117
- `unwritable-link` is refused by `apply`, not by `validate`, so no case under
118
- `cases/` carries it.
118
+ `unwritable-link` is refused by `apply` and `division-budget` by `divide`, not
119
+ by `validate`, so no case under `cases/` carries either.
119
120
 
120
121
  ## YAML subset
121
122
 
@@ -319,6 +319,22 @@
319
319
  }
320
320
  }
321
321
  },
322
+ {
323
+ "name": "a budget that cannot hold one whole character is refused before any division",
324
+ "file": "notes/one.md",
325
+ "source": "## Notes\n\nShort note.\n",
326
+ "documentTargets": [],
327
+ "definition": null,
328
+ "budget": 1,
329
+ "expected": {
330
+ "ok": false,
331
+ "refusal": {
332
+ "file": "notes/one.md",
333
+ "rule": "division-budget",
334
+ "version": "<package-version>"
335
+ }
336
+ }
337
+ },
322
338
  {
323
339
  "name": "a free-text value the author quoted embeds bare and addresses the quotes it was written with",
324
340
  "file": "tasks/one.md",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/mdmodel",
3
- "version": "0.1.0-alpha.10",
3
+ "version": "0.1.0-alpha.11",
4
4
  "description": "MD Type language, parser, validator, structured change application, Markdown syntax profile, and conformance fixtures",
5
5
  "license": "MIT",
6
6
  "type": "module",