@linloir/limr 0.1.0 → 1.0.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.
Files changed (97) hide show
  1. package/README.en.md +151 -0
  2. package/README.md +80 -127
  3. package/benchmarks/results/layout.json +2593 -0
  4. package/benchmarks/results/markstream-code.json +1823 -0
  5. package/benchmarks/results/markstream-reading-repeat.json +1152 -0
  6. package/benchmarks/results/markstream.json +12486 -0
  7. package/benchmarks/results/streaming-browser.json +77 -0
  8. package/benchmarks/results/streaming.json +357 -0
  9. package/dist/base.css +93 -10
  10. package/dist/{chunk-7JF5HHVF.js → chunk-BG5QUQFR.js} +340 -72
  11. package/dist/chunk-BG5QUQFR.js.map +1 -0
  12. package/dist/chunk-BVHHOVMT.js +179 -0
  13. package/dist/chunk-BVHHOVMT.js.map +1 -0
  14. package/dist/chunk-FJZCQY2S.js +155 -0
  15. package/dist/chunk-FJZCQY2S.js.map +1 -0
  16. package/dist/chunk-FSI5OTBW.js +1 -0
  17. package/dist/{chunk-ETHLPBKQ.js → chunk-GU2RPESF.js} +238 -131
  18. package/dist/chunk-GU2RPESF.js.map +1 -0
  19. package/dist/{chunk-65V5OZ4G.js → chunk-SUAAUGAX.js} +1350 -511
  20. package/dist/chunk-SUAAUGAX.js.map +1 -0
  21. package/dist/core/index.d.ts +6 -3
  22. package/dist/core/index.js +15 -5
  23. package/dist/extensions/index.d.ts +30 -5
  24. package/dist/extensions/index.js +15 -3
  25. package/dist/index.d.ts +4 -4
  26. package/dist/index.js +31 -8
  27. package/dist/{engine-43u8B4yt.d.ts → knuth-plass-C8mgFm7W.d.ts} +67 -1
  28. package/dist/knuth-plass-layout-CHQCWKB5.js +449 -0
  29. package/dist/knuth-plass-layout-CHQCWKB5.js.map +1 -0
  30. package/dist/react/index.d.ts +7 -5
  31. package/dist/react/index.js +7 -3
  32. package/dist/styles.css +93 -10
  33. package/dist/{translations-BliabrPd.d.ts → translations-BXzSwLBJ.d.ts} +49 -4
  34. package/docs/README.md +13 -0
  35. package/docs/api.md +5 -158
  36. package/docs/assets/rendered.svg +9 -0
  37. package/docs/assets/source.svg +9 -0
  38. package/docs/en/README.md +28 -0
  39. package/docs/en/ai-skills.md +57 -0
  40. package/docs/en/annotations.md +86 -0
  41. package/docs/en/api.md +115 -0
  42. package/docs/en/architecture.md +41 -0
  43. package/docs/en/extensions.md +208 -0
  44. package/docs/en/getting-started.md +69 -0
  45. package/docs/en/integration.md +154 -0
  46. package/docs/en/modules.md +84 -0
  47. package/docs/en/performance.md +93 -0
  48. package/docs/en/plugin-packages.md +68 -0
  49. package/docs/en/styles.md +99 -0
  50. package/docs/en/syntax.md +455 -0
  51. package/docs/extensions.md +5 -306
  52. package/docs/implementation.md +5 -76
  53. package/docs/performance.md +5 -81
  54. package/docs/screenshots/blocks.png +0 -0
  55. package/docs/screenshots/dark.png +0 -0
  56. package/docs/screenshots/desktop.png +0 -0
  57. package/docs/screenshots/plugin-mobile.png +0 -0
  58. package/docs/styles.md +5 -100
  59. package/docs/visual-upgrade.md +5 -145
  60. package/docs/zh-CN/README.md +28 -0
  61. package/docs/zh-CN/ai-skills.md +57 -0
  62. package/docs/zh-CN/annotations.md +86 -0
  63. package/docs/zh-CN/api.md +115 -0
  64. package/docs/zh-CN/architecture.md +41 -0
  65. package/docs/zh-CN/extensions.md +210 -0
  66. package/docs/zh-CN/getting-started.md +69 -0
  67. package/docs/zh-CN/integration.md +154 -0
  68. package/docs/zh-CN/modules.md +84 -0
  69. package/docs/zh-CN/performance.md +93 -0
  70. package/docs/zh-CN/plugin-packages.md +68 -0
  71. package/docs/zh-CN/styles.md +99 -0
  72. package/docs/zh-CN/syntax.md +457 -0
  73. package/examples/notes.tsx +18 -11
  74. package/examples/packages/paper-theme/index.css +25 -0
  75. package/examples/packages/paper-theme/package.json +7 -0
  76. package/examples/packages/reading-tools/index.d.ts +2 -0
  77. package/examples/packages/reading-tools/index.js +25 -0
  78. package/examples/packages/reading-tools/package.json +16 -0
  79. package/package.json +17 -5
  80. package/skills/limr-plugin-development/SKILL.md +22 -0
  81. package/skills/limr-plugin-development/agents/openai.yaml +4 -0
  82. package/skills/limr-plugin-development/assets/plugin-template/README.md +30 -0
  83. package/skills/limr-plugin-development/assets/plugin-template/package.json +36 -0
  84. package/skills/limr-plugin-development/assets/plugin-template/src/index.tsx +50 -0
  85. package/skills/limr-plugin-development/assets/plugin-template/src/styles.css +9 -0
  86. package/skills/limr-plugin-development/assets/plugin-template/tsconfig.json +20 -0
  87. package/skills/limr-plugin-development/assets/plugin-template/tsup.config.ts +8 -0
  88. package/skills/limr-plugin-development/references/contract.md +51 -0
  89. package/skills/limr-use/SKILL.md +23 -0
  90. package/skills/limr-use/agents/openai.yaml +4 -0
  91. package/skills/limr-use/references/integration.md +49 -0
  92. package/skills/limr-use/references/syntax.md +20 -0
  93. package/dist/chunk-65V5OZ4G.js.map +0 -1
  94. package/dist/chunk-7JF5HHVF.js.map +0 -1
  95. package/dist/chunk-ETHLPBKQ.js.map +0 -1
  96. package/dist/chunk-V2OG4Y3F.js +0 -1
  97. /package/dist/{chunk-V2OG4Y3F.js.map → chunk-FSI5OTBW.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/parser.ts","../src/core/streaming.ts","../src/core/engine.ts","../src/core/selection.ts","../src/core/annotations.ts"],"sourcesContent":["import { fromMarkdown } from 'mdast-util-from-markdown';\nimport { mdxJsx } from 'micromark-extension-mdx-jsx';\nimport { mdxJsxFromMarkdown } from 'mdast-util-mdx-jsx';\nimport { directive } from 'micromark-extension-directive';\nimport { directiveFromMarkdown } from 'mdast-util-directive';\nimport { lineStarts, sourcePoint, walk } from './tree';\nimport { concealIncomplete, prepareSource } from './streaming';\nimport type { Diagnostic, MarkdownNode, ParseContext, SourcePosition, SyntaxExtension } from './types';\n\nexport function validateExtensions(extensions: readonly SyntaxExtension[]): void {\n const names = new Set<string>();\n const tags = new Set<string>();\n const directives = new Set<string>();\n const owners = new Map<string, SyntaxExtension>();\n for (const extension of extensions) {\n if (names.has(extension.name)) throw new Error(`Duplicate LiMR extension: ${extension.name}. Use replaceExtension() to replace it explicitly.`);\n names.add(extension.name);\n for (const [items, known, kind] of [[extension.tags, tags, 'tag'], [extension.directives, directives, 'directive']] as const) {\n for (const name of items ?? []) {\n if (known.has(name)) throw new Error(`Duplicate LiMR ${kind}: ${name}`);\n known.add(name);\n }\n }\n for (const name of [...extension.tags ?? [], ...extension.directives ?? []]) {\n if (owners.has(name) && owners.get(name) !== extension) throw new Error(`Duplicate LiMR component syntax: ${name}`);\n owners.set(name, extension);\n }\n }\n}\n\nexport function createParser(extensions: readonly SyntaxExtension[]) {\n validateExtensions(extensions);\n const tagDefinitions = new Map(extensions.flatMap(ext => (ext.tags ?? []).map(name => [name, ext] as const)));\n const directiveDefinitions = new Map(extensions.flatMap(ext => [...new Set([...ext.tags ?? [], ...ext.directives ?? []])].map(name => [name, ext] as const)));\n const names = new Set(directiveDefinitions.keys()), tags = new Set(tagDefinitions.keys());\n const literals = new Set([...directiveDefinitions].filter(([, definition]) => definition.literal).map(([name]) => name));\n const syntax = extensions.flatMap(ext => [...ext.micromark ?? []]);\n const mdast = extensions.flatMap(ext => [...ext.mdast ?? []]);\n const plainSyntax = [...syntax], plainMdast = [...mdast];\n if (directiveDefinitions.size) { syntax.push(directive()); mdast.push(directiveFromMarkdown()); }\n // CommonMark's HTML blocks otherwise swallow same-line native tag names such\n // as <figcaption>**caption**</figcaption> before the JSX adapter can see them.\n // Unknown JSX remains inert through the whitelist below; recovery keeps HTML.\n const jsxSyntax = tagDefinitions.size ? [...syntax, { disable: { null: ['htmlFlow', 'htmlText'] } }, mdxJsx()] : syntax;\n const jsxMdast = tagDefinitions.size ? [...mdast, mdxJsxFromMarkdown()] : mdast;\n const plainJsxSyntax = [...plainSyntax, { disable: { null: ['htmlFlow', 'htmlText'] } }, mdxJsx()];\n const plainJsxMdast = [...plainMdast, mdxJsxFromMarkdown()];\n let literalCache: { fragment: string; offset: number; node: MarkdownNode; fence: string; content: number } | undefined;\n\n return (fragment: string, offset: number, context: ParseContext, lines: readonly number[], environment = '') => {\n // Definitions are a parsing environment, never part of the stored source.\n // A known prefix offset is removed from EVERY node position below.\n // A neutral paragraph closes footnote containers. Without it, an indented\n // suffix can be consumed as part of a synthetic footnote definition.\n const prefix = environment ? `${environment}\\n\\nlimr-definition-boundary\\n\\n` : '';\n const cached = literalCache;\n const canAppendLiteral = context.streaming && cached && !prefix && cached.offset === offset && fragment.startsWith(cached.fragment)\n && !new RegExp(`(?:^|[\\\\r\\\\n]) {0,3}${cached.fence[0]}{${cached.fence.length},}[ \\\\t]*(?=[\\\\r\\\\n]|$)`).test(fragment.slice(Math.max(cached.content, cached.fragment.lastIndexOf('\\n') + 1, cached.fragment.lastIndexOf('\\r') + 1)));\n const prepared = canAppendLiteral\n ? { value: fragment, original: (at: number) => at, incomplete: new Set([0]), recoveryOffset: 0, hidden: undefined }\n : prepareSource(fragment, names, tags, context.streaming, literals);\n const input = prefix + prepared.value;\n // Ordinary prose need not install component tokenizers on every append.\n // Colon-prefixed names and '<' are required even for partial constructs.\n const hasDirectives = directiveDefinitions.size > 0 && /:[a-zA-Z]/.test(input);\n const hasJsx = tagDefinitions.size > 0 && input.includes('<');\n const activeSyntax = hasDirectives ? syntax : plainSyntax, activeMdast = hasDirectives ? mdast : plainMdast;\n const mappedOffset = (at: number) => offset + prepared.original(Math.max(0, at - prefix.length));\n const mappedLines = lines.length ? lines : lineStarts(context.source);\n const diagnostics: Diagnostic[] = [];\n let attributeLines: readonly number[] | undefined;\n const attributePoint = (at: number) => sourcePoint(at, lines.length ? lines : attributeLines ??= lineStarts(context.source));\n let recoveryOffset = prepared.recoveryOffset === undefined ? undefined : offset + prepared.recoveryOffset;\n let root: MarkdownNode;\n try {\n root = canAppendLiteral ? { type: 'root', children: [{ ...cached.node,\n value: fragment.slice(cached.content).replace(/(?:\\r\\n|\\r|\\n)$/, ''),\n position: { start: { offset: 0, line: 1, column: 1 }, end: { offset: fragment.length, line: 0, column: 0 } },\n }] } : fromMarkdown(input, { extensions: hasJsx ? hasDirectives ? jsxSyntax : plainJsxSyntax : activeSyntax, mdastExtensions: hasJsx ? hasDirectives ? jsxMdast : plainJsxMdast : activeMdast }) as unknown as MarkdownNode;\n } catch (error) {\n // Incomplete JSX is common during streaming. Preserve readable Markdown,\n // treat HTML as inert source and retry the final block on the next append.\n root = fromMarkdown(input, { extensions: activeSyntax, mdastExtensions: activeMdast }) as unknown as MarkdownNode;\n recoveryOffset = offset;\n diagnostics.push({ message: error instanceof Error ? error.message : String(error), offset });\n }\n root.children = root.children?.filter(node => (node.position?.start.offset ?? 0) >= prefix.length);\n const only = root.children?.length === 1 ? root.children[0] : undefined;\n const fence = !prefix && only?.type === 'code' && prepared.incomplete.has(0) && /^(`{3,}|~{3,})[^\\r\\n]*(?:\\r\\n|\\r|\\n)/.exec(fragment);\n literalCache = fence ? { fragment, offset, node: { ...only! }, fence: fence[1], content: fence[0].length } : undefined;\n if (offset || prefix.length || tagDefinitions.size || directiveDefinitions.size || context.streaming) walk(root, node => {\n if (node.position && (offset || prefix.length || prepared.value !== fragment || canAppendLiteral)) {\n const start = mappedOffset(node.position.start.offset);\n const end = Math.max(start, mappedOffset(node.position.end.offset));\n node.position = { start: sourcePoint(start, mappedLines), end: sourcePoint(end, mappedLines) };\n }\n if (node.position && prepared.incomplete.has(node.position.start.offset - offset)) node.incomplete = true;\n if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {\n const definition = tagDefinitions.get(node.name ?? '');\n const rawAttributes = node.attributes as unknown as { type: string; name: string; value: unknown; position?: SourcePosition }[];\n const attributes: Record<string, string | boolean | number> = {};\n const attributeNodes: Record<string, MarkdownNode> = {};\n for (const attr of rawAttributes ?? []) {\n if (attr.type === 'mdxJsxAttribute' && (typeof attr.value === 'string' || attr.value === null)) {\n attributes[attr.name] = attr.value ?? true;\n if (definition && typeof attr.value === 'string' && attr.position) {\n const start = mappedOffset(attr.position.start.offset);\n const end = mappedOffset(attr.position.end.offset);\n const raw = context.source.slice(start, end), opening = raw.search(/[\"']/);\n if (opening >= 0) attributeNodes[attr.name] = { type: 'text', value: attr.value, verbatimEscapes: true, position: { start: attributePoint(start + opening + 1), end: attributePoint(end - 1) } };\n }\n }\n else diagnostics.push({ message: 'JSX expressions are not executed. Use string attributes or pass data from React.', offset: node.position?.start.offset });\n }\n node.inline = definition?.display === 'block' ? false : definition?.display === 'inline' ? true : node.type === 'mdxJsxTextElement';\n node.type = definition ? 'component' : 'html';\n node.attributes = attributes;\n if (Object.keys(attributeNodes).length) node.attributeNodes = attributeNodes;\n node.selection = definition?.selection ?? 'content';\n if (!definition && node.position) {\n node.value = context.source.slice(node.position.start.offset, node.position.end.offset);\n node.children = undefined;\n }\n } else if (node.type === 'containerDirective' || node.type === 'leafDirective' || node.type === 'textDirective') {\n const definition = directiveDefinitions.get(node.name ?? '');\n if (definition) {\n // Directive attributes have no mdast positions. Scan only their header,\n // respecting quoted values instead of searching the rendered title.\n const start = node.position?.start.offset ?? 0;\n const end = context.source.indexOf('\\n', start);\n const header = context.source.slice(start, end < 0 ? context.source.length : end);\n const brace = header.indexOf('{');\n if (brace >= 0) {\n const attributeNodes: Record<string, MarkdownNode> = {};\n const expression = /([^\\s{}=]+)\\s*=\\s*(?:\"((?:\\\\.|[^\"\\\\])*)\"|'((?:\\\\.|[^'\\\\])*)'|([^\\s}]+))/g;\n const raw = header.slice(brace + 1);\n for (const match of raw.matchAll(expression)) {\n const name = match[1], value = node.attributes?.[name];\n if (typeof value !== 'string') continue;\n const quoted = match[2] !== undefined || match[3] !== undefined;\n const valueLength = (match[2] ?? match[3] ?? match[4]).length;\n const valueEnd = start + brace + 1 + match.index! + match[0].length - (quoted ? 1 : 0);\n attributeNodes[name] = { type: 'text', value, position: { start: attributePoint(valueEnd - valueLength), end: attributePoint(valueEnd) } };\n }\n if (Object.keys(attributeNodes).length) node.attributeNodes = attributeNodes;\n }\n node.inline = node.type === 'textDirective';\n node.type = 'component';\n node.selection = definition.selection ?? 'content';\n }\n }\n });\n if (prepared.hidden) {\n const start = offset + prepared.hidden.start;\n // A withheld inline header can still belong to the preceding paragraph.\n // Retry that host too instead of retaining a prematurely split block.\n recoveryOffset = Math.min(recoveryOffset ?? start, root.children?.at(-1)?.position?.start.offset ?? start);\n root.children?.push({ type: prepared.hidden.name ? 'component' : 'streamPending', name: prepared.hidden.name, incomplete: true,\n position: { start: sourcePoint(start, mappedLines), end: sourcePoint(offset + fragment.length, mappedLines) }, children: [], attributes: {} });\n }\n if (context.streaming) concealIncomplete(root, context.source, mappedLines);\n if (offset || prefix.length) root.position = { start: sourcePoint(offset, mappedLines), end: sourcePoint(offset + fragment.length, mappedLines) };\n for (const extension of extensions) {\n try { extension.transform?.(root, context); }\n catch (error) { diagnostics.push({ message: error instanceof Error ? error.message : String(error), extension: extension.name }); }\n }\n return { nodes: root.children ?? [], diagnostics, recoveryOffset };\n };\n}\n","import type { MarkdownNode } from './types';\nimport { sourcePoint, walk } from './tree';\nimport { decodeString } from 'micromark-util-decode-string';\n\ninterface Edit { at: number; insert: string; order?: number }\ninterface Region { start: number; end: number }\ninterface Container { start: number; marker: number; size: number; depth: number; close?: number; end?: number; leaf?: boolean; content?: number; prefix?: string }\nexport interface PreparedSource {\n value: string;\n original: (offset: number) => number;\n incomplete: ReadonlySet<number>;\n recoveryOffset?: number;\n hidden?: { start: number; name?: string };\n}\n\n/** Only parser input is adapted. All public offsets still address the original\n * string. Insertions use a sparse map, not one allocation per source character. */\nfunction insertions(source: string, edits: Edit[]) {\n edits.sort((a, b) => a.at - b.at || (a.order ?? 0) - (b.order ?? 0));\n const parts: string[] = [], points: { from: number; to: number; at: number; delta: number }[] = [];\n let at = 0, delta = 0;\n for (const edit of edits) {\n parts.push(source.slice(at, edit.at), edit.insert);\n points.push({ from: edit.at + delta, to: edit.at + delta + edit.insert.length, at: edit.at, delta: delta + edit.insert.length });\n at = edit.at; delta += edit.insert.length;\n }\n parts.push(source.slice(at));\n return {\n value: parts.join(''),\n original(offset: number) {\n let lo = 0, hi = points.length;\n while (lo < hi) { const mid = (lo + hi) >>> 1; if (points[mid].from <= offset) lo = mid + 1; else hi = mid; }\n const point = points[lo - 1];\n return Math.min(source.length, point ? offset < point.to ? point.at : offset - point.delta : offset);\n },\n };\n}\n\n/** Adapt CoMark's two-colon containers to the existing directive tokenizer.\n * Paired containers may nest with the same fence length. Unpaired two-colon\n * lines in a finished document retain the legacy leaf-directive meaning. */\nexport function prepareSource(source: string, names: ReadonlySet<string>, tags: ReadonlySet<string>, streaming: boolean, literals: ReadonlySet<string> = new Set()): PreparedSource {\n if ((!streaming && (!names.size || !source.includes('::'))) || !/[<:`~$]/.test(source)) return { value: source, original: at => at, incomplete: new Set() };\n const edits: Edit[] = [], protectedRegions: Region[] = [];\n const incomplete = new Set<number>();\n const containers: Container[] = [], stack: Container[] = [];\n let fence: { start: number; marker: string; size: number } | undefined;\n let hidden: PreparedSource['hidden'];\n let literal: Container | undefined;\n let maxDepth = 0;\n // Lists and block quotes keep their prefixes; inserted colons never move the\n // AST out of its Markdown parent. Indented code remains literal.\n const lines = /[^\\r\\n]*(?:\\r\\n|\\r|\\n|$)/g;\n for (const match of source.matchAll(lines)) {\n if (!match[0]) continue;\n const line = match[0].replace(/[\\r\\n]+$/, ''), at = match.index!;\n const prefix = /^(?: {0,3}>[ \\t]?)*(?: {0,3}(?:[-+*]|\\d+[.)])[ \\t]+)? {0,3}/.exec(line)![0];\n const body = line.slice(prefix.length), start = at + prefix.length;\n if (literal && !/^:{2,}[ \\t]*$/.test(body)) continue;\n if (literal) { protectedRegions.push({ start: literal.content!, end: at }); literal = undefined; }\n if (fence) {\n if (new RegExp(`^${fence.marker}{${fence.size},}[ \\\\t]*$`).test(body)) {\n protectedRegions.push({ start: fence.start, end: at + match[0].length }); fence = undefined;\n }\n continue;\n }\n const openingFence = /^(`{3,}|~{3,}|\\${2,})(.*)$/.exec(body);\n if (openingFence && !(openingFence[1][0] === '`' && openingFence[2].includes('`'))) {\n fence = { start, marker: openingFence[1][0] === '$' ? '\\\\$' : openingFence[1][0], size: openingFence[1].length };\n if (streaming && !/[\\r\\n]$/.test(match[0])) hidden = { start };\n continue;\n }\n // Four-space code is never component syntax.\n if (/^[ \\t]/.test(body)) { protectedRegions.push({ start: at, end: at + match[0].length }); continue; }\n const open = /^(:{2,})([a-zA-Z][\\w-]*)(.*)$/.exec(body);\n if (open && names.has(open[2])) {\n const rest = open[3].trim();\n const validHeader = /^(?:\\[(?:\\\\.|[^\\]])*\\])?(?:\\{(?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|[^{}\"'])*\\})?$/.test(rest);\n if (!validHeader) {\n if (streaming && at + match[0].length === source.length) hidden = { start, name: open[2] };\n continue;\n }\n const item: Container = { start, marker: start, size: open[1].length, depth: stack.length };\n containers.push(item); stack.push(item); maxDepth = Math.max(maxDepth, item.depth);\n if (literals.has(open[2]) && /[\\r\\n]$/.test(match[0])) { item.content = at + match[0].length; item.prefix = prefix.replace(/[-+*]|\\d+[.)]/g, value => ' '.repeat(value.length)); literal = item; }\n continue;\n }\n const closing = /^(:{2,})[ \\t]*$/.exec(body);\n if (closing && stack.length) {\n if (closing[1].length > 2) {\n let ancestor = -1;\n for (let index = stack.length - 1; index >= 0; index--) if (stack[index].size > 2 && stack[index].size <= closing[1].length) { ancestor = index; break; }\n if (ancestor >= 0) for (const leaf of stack.splice(ancestor + 1)) leaf.leaf = true;\n }\n const item = stack[stack.length - 1];\n if (closing[1].length >= item.size) { item.close = start; item.end = at + line.length; stack.pop(); }\n } else if (streaming && /^::[\\w-]*$/.test(body) && at + match[0].length === source.length) hidden = { start };\n }\n if (fence) {\n protectedRegions.push({ start: fence.start, end: source.length });\n if (streaming) incomplete.add(fence.start);\n }\n if (literal) protectedRegions.push({ start: literal.content!, end: source.length });\n const active = containers.filter(item => !item.leaf && (item.close !== undefined || streaming));\n // The outer fence must be longer than its children for mdast directives.\n // Existing standalone ::: syntax is left byte-for-byte intact.\n const hasDouble = active.some(item => item.size === 2);\n const maxSize = Math.max(3, ...active.map(value => value.size));\n if (hasDouble) for (const item of active) {\n const width = maxSize + maxDepth - item.depth;\n if (width > item.size) edits.push({ at: item.marker, insert: ':'.repeat(width - item.size) });\n if (item.close !== undefined) {\n const size = /^:+/.exec(source.slice(item.close))![0].length;\n if (width > size) edits.push({ at: item.close, insert: ':'.repeat(width - size) });\n }\n }\n for (const item of active) if (item.content !== undefined) {\n const payload = source.slice(item.content, item.close ?? source.length);\n const fence = '~'.repeat(Math.max(3, ...[...payload.matchAll(/~+/g)].map(match => match[0].length + 1)));\n edits.push({ at: item.content, insert: `${item.prefix}${fence}\\n`, order: -2 });\n if (item.close !== undefined) edits.push({ at: item.close, insert: `${fence}\\n${item.prefix}`, order: -1 });\n }\n if (streaming) for (const item of stack) incomplete.add(item.start);\n\n // Balance registered JSX in parser input only. A half header is withheld;\n // complete open tags retain their identity and can show a module-owned state.\n const openTags: { name: string; start: number; block: boolean }[] = [];\n if (streaming && tags.size && source.includes('<')) {\n let region = 0, codeTicks = 0, codeStart = 0;\n for (let i = 0; i < (hidden?.start ?? source.length); i++) {\n while (protectedRegions[region] && protectedRegions[region].end <= i) region++;\n if (protectedRegions[region]?.start <= i) { i = protectedRegions[region].end - 1; continue; }\n if (source[i] === '\\\\') { i++; continue; }\n if (!codeTicks && names.has('math') && source[i] === '$') {\n const size = /^\\$+/.exec(source.slice(i))![0].length;\n const close = source.indexOf('$'.repeat(size), i + size);\n if (close < 0) { hidden = { start: i }; break; }\n i = close + size - 1;\n continue;\n }\n if (source[i] === '`') {\n const size = /^`+/.exec(source.slice(i))![0].length;\n if (!codeTicks) { codeTicks = size; codeStart = i; } else if (codeTicks === size) codeTicks = 0;\n i += size - 1; continue;\n }\n if (codeTicks || source[i] !== '<') continue;\n const head = /^<(\\/?)([a-zA-Z][\\w-]*)/.exec(source.slice(i));\n if (!head) {\n if (/^<\\/?$/.test(source.slice(i))) hidden = { start: i };\n continue;\n }\n const name = head[2];\n if (!tags.has(name)) {\n if ([...tags].some(tag => tag.startsWith(name)) && i + head[0].length === source.length) hidden = { start: i };\n continue;\n }\n let end = i + head[0].length, quote = '';\n for (; end < source.length; end++) {\n const char = source[end];\n if (quote) { if (char === quote) quote = ''; }\n else if (char === '\"' || char === \"'\") quote = char;\n else if (char === '>') break;\n }\n if (end === source.length) { hidden = { start: i, name: head[1] ? undefined : name }; break; }\n if (head[1]) { if (openTags.at(-1)?.name === name) openTags.pop(); }\n else if (source[end - 1] !== '/') openTags.push({ name, start: i, block: /^(?: {0,3}> ?)*\\s*$/.test(source.slice(source.lastIndexOf('\\n', i - 1) + 1, i)) && /^[ \\t]*(?:\\r?\\n|$)/.test(source.slice(end + 1)) });\n i = end;\n }\n if (codeTicks) hidden = { start: Math.min(codeStart, hidden?.start ?? source.length) };\n }\n for (const tag of openTags) incomplete.add(tag.start);\n const cutoff = hidden?.start ?? source.length;\n const mapped = insertions(source.slice(0, cutoff), edits.filter(edit => edit.at < cutoff));\n const suffix = openTags.reverse().map(tag => `${tag.block ? '\\n\\n' : ''}</${tag.name}>`).join('');\n return { ...mapped, value: mapped.value + suffix, incomplete, hidden,\n recoveryOffset: incomplete.size || hidden ? Math.min(...incomplete, hidden?.start ?? Infinity) : undefined };\n}\n\n/** Incomplete inline punctuation must not flash as literal Markdown. Complete\n * syntax already has its own AST node, so this only examines trailing text. */\nexport function concealIncomplete(root: MarkdownNode, source: string, lines: readonly number[]) {\n const tail = root.children?.at(-1);\n if (tail?.type === 'paragraph' && tail.position) {\n const raw = source.slice(tail.position.start.offset);\n if (/^ {0,3}\\|[^\\r\\n]*(?:(?:\\r\\n|\\r|\\n)[|:\\- \\t]*)?$/.test(raw)) { tail.children = []; return; }\n }\n let cutoff = source.length;\n walk(root.children?.at(-1) ?? root, node => {\n if (node.type !== 'text' || !node.position) return;\n const { start, end } = node.position;\n const raw = source.slice(start.offset);\n for (const candidate of raw.slice(0, end.offset - start.offset).matchAll(/[!\\[`*_~\\$&^]/g)) {\n const at = candidate.index!;\n let escapes = 0;\n for (let before = at - 1; before >= 0 && raw[before] === '\\\\'; before--) escapes++;\n if (escapes % 2) continue;\n if (raw[at] === '_' && /[\\p{L}\\p{N}]/u.test(raw[at - 1] ?? '') && /[\\p{L}\\p{N}]/u.test(raw[at + 1] ?? '')) continue;\n const tail = raw.slice(at).trimEnd();\n if (/^(?:\\^\\[[^\\]]*$|!?(?:\\[[^\\]]*$|\\[[^\\]]*\\]\\([^)]*$)|`+[^`]*$|\\*{1,3}(?:\\S[^*]*)?$|_{1,3}(?:\\S[^_]*)?$|~{1,2}(?:\\S[^~]*)?$|\\$[^$]*$|&(?:#x?[\\da-f]*|[a-z]*)$)/i.test(tail)) { cutoff = Math.min(cutoff, start.offset + at); break; }\n }\n });\n if (cutoff === source.length) return;\n walk(root, node => {\n if (node.children) node.children = node.children.filter(child => (child.position?.start.offset ?? 0) < cutoff);\n if (node.type !== 'text' || !node.position || node.position.end.offset <= cutoff) return;\n node.value = decodeString(source.slice(node.position.start.offset, cutoff));\n node.position = { start: node.position.start, end: sourcePoint(cutoff, lines) };\n });\n}\n","import { createParser } from './parser';\nimport { lineStarts, rangeOf, slugify, textContent, walk } from './tree';\nimport type { Annotation, AnnotationOccurrence, Block, DocumentMetrics, DocumentOptions, DocumentSnapshot, Heading, MarkdownNode, SyntaxExtension } from './types';\n\nlet sequence = 0;\n\n/** A synchronous, DOM-free document session. React/scroll state never enters it. */\nexport class DocumentEngine {\n readonly id: string;\n private extensions: readonly SyntaxExtension[];\n private parse: ReturnType<typeof createParser>;\n private snapshot?: DocumentSnapshot;\n private nextBlock = 0;\n private listeners = new Set<() => void>();\n private definitionSignature = '';\n private recoveryOffset: number | undefined;\n private lines: number[] = [0];\n private facts = new WeakMap<MarkdownNode, readonly MarkdownNode[]>();\n private relevant(node: MarkdownNode): readonly MarkdownNode[] {\n let result = this.facts.get(node);\n if (!result) {\n const nodes: MarkdownNode[] = [];\n walk(node, child => { if (child.annotation || ['heading', 'definition', 'footnoteDefinition', 'footnoteReference', 'annotationDefinition', 'annotationReference'].includes(child.type)) nodes.push(child); });\n this.facts.set(node, result = nodes);\n }\n return result;\n }\n\n constructor(source = '', options: DocumentOptions = {}) {\n this.id = options.id ?? `limr-${++sequence}`;\n this.extensions = options.extensions ?? [];\n this.parse = createParser(this.extensions);\n this.update(source, { streaming: options.streaming });\n }\n\n getSnapshot = (): DocumentSnapshot => this.snapshot!;\n subscribe = (listener: () => void): (() => void) => { this.listeners.add(listener); return () => this.listeners.delete(listener); };\n\n setExtensions(extensions: readonly SyntaxExtension[]): void {\n if (extensions === this.extensions) return;\n this.parse = createParser(extensions);\n this.extensions = extensions;\n const previous = this.snapshot!;\n this.update(previous.source, { streaming: previous.streaming }, true);\n }\n\n append(chunk: string): DocumentSnapshot { return this.update(this.snapshot!.source + chunk, { streaming: true }); }\n finish(): DocumentSnapshot { return this.update(this.snapshot!.source, { streaming: false }); }\n\n update(source: string, options: { streaming?: boolean } = {}, force = false): DocumentSnapshot {\n const previous = this.snapshot;\n const streaming = options.streaming ?? false;\n if (!force && previous?.source === source && previous.streaming === streaming) return previous;\n const globalTransform = this.extensions.some(ext => ext.transform && ext.scope !== 'local');\n const append = !force && previous?.streaming && source.startsWith(previous.source) && !globalTransform;\n const finalizing = !!previous?.streaming && !streaming;\n let start = append && previous.blocks.length ? previous.blocks[previous.blocks.length - 1].range.start : 0;\n const recovering = this.recoveryOffset !== undefined;\n if (append && recovering) start = Math.min(start, this.recoveryOffset!);\n let reason: DocumentMetrics['reason'] = force || globalTransform ? 'extension' : !previous ? 'initial' : finalizing ? 'finalize' : append ? 'append' : 'replace';\n if (append && previous) {\n // Rescan the last code unit as CR and LF may arrive in separate chunks.\n const from = Math.max(0, previous.source.length - 1);\n while (this.lines.length > 1 && this.lines.at(-1)! > from) this.lines.pop();\n for (const at of lineStarts(source.slice(from)).slice(1)) this.lines.push(from + at);\n } else this.lines = lineStarts(source);\n const lines = this.lines;\n const context = { source, streaming, documentId: this.id };\n let retained = start ? previous!.blocks.filter(block => block.range.end <= start) : [];\n const environment: string[] = [];\n for (const block of retained) for (const node of this.relevant(block.node)) {\n if (node.type === 'definition' || node.type === 'footnoteDefinition') { const range = rangeOf(node); environment.push(source.slice(range.start, range.end)); }\n }\n let parsed = this.parse(source.slice(start), start, context, lines, environment.join('\\n\\n'));\n const getSignature = (nodes: readonly MarkdownNode[]) => {\n const entries: string[] = [];\n for (const node of nodes) for (const child of this.relevant(node)) {\n if (child.type === 'definition' || child.type === 'footnoteDefinition') { const range = rangeOf(child); entries.push(source.slice(range.start, range.end)); }\n }\n return entries.join('\\u0000');\n };\n let signature = getSignature([...retained.map(block => block.node), ...parsed.nodes]);\n let parsedCharacters = source.length - start + environment.join('\\n\\n').length;\n const definitionsChanged = !!previous && signature !== this.definitionSignature;\n if (start && definitionsChanged) {\n reason = 'definitions';\n start = 0;\n retained = [];\n parsed = this.parse(source, 0, context, lines);\n signature = getSignature(parsed.nodes);\n parsedCharacters += source.length;\n }\n this.definitionSignature = signature;\n this.recoveryOffset = parsed.recoveryOffset;\n const oldAt = new Map(previous?.blocks.slice(retained.length).map(block => [block.range.start, block]));\n let reused = retained.length;\n const blocks: Block[] = [...retained];\n for (let index = 0; index < parsed.nodes.length; index++) {\n const node = parsed.nodes[index];\n const range = rangeOf(node);\n const old = oldAt.get(range.start);\n const pending = streaming && index === parsed.nodes.length - 1;\n // Definition changes can change semantic nodes without changing their raw text.\n const reusable = !definitionsChanged && !recovering && reason === 'append' && old && old.node.type === node.type && old.pending === pending && previous!.source.slice(old.range.start, old.range.end) === source.slice(range.start, range.end);\n if (reusable) { blocks.push(old); reused++; }\n else blocks.push({ id: old?.id ?? `${this.id}-b${++this.nextBlock}`, node, range, pending });\n }\n const headings: Heading[] = [];\n const definitions = new Map<string, MarkdownNode>();\n const footnotes = new Map<string, MarkdownNode>();\n const footnoteOrder: string[] = [];\n const annotations = new Map<string, Annotation>();\n const occurrences: AnnotationOccurrence[] = [];\n const slugCounts = new Map<string, number>();\n for (const block of blocks) for (const node of this.relevant(block.node)) {\n if (node.type === 'heading') {\n const text = textContent(node);\n const base = slugify(text);\n const count = slugCounts.get(base) ?? 0;\n slugCounts.set(base, count + 1);\n headings.push({ id: `${this.id}-${base}${count ? `-${count}` : ''}`, text, level: Number(node.depth), range: rangeOf(node), blockId: block.id });\n }\n if (node.type === 'definition' && !definitions.has(String(node.identifier))) definitions.set(String(node.identifier), node);\n if (node.type === 'footnoteDefinition' && !footnotes.has(String(node.identifier))) footnotes.set(String(node.identifier), node);\n if (node.type === 'footnoteReference' && !footnoteOrder.includes(String(node.identifier))) footnoteOrder.push(String(node.identifier));\n if (node.annotation) {\n const annotation = node.annotation as Annotation;\n // GFM resolves duplicate named footnotes to their first definition.\n if (node.type !== 'footnoteDefinition' || !annotations.has(annotation.id)) annotations.set(annotation.id, annotation);\n }\n if (node.type === 'annotationReference') {\n const range = rangeOf(node);\n occurrences.push({ id: `${this.id}-ref-${range.start}`, range, annotationIds: node.annotationIds as string[], embedded: true, ...(node.referenceRange ? { referenceRange: node.referenceRange as AnnotationOccurrence['referenceRange'] } : {}) });\n }\n }\n this.snapshot = {\n id: this.id, revision: (previous?.revision ?? -1) + 1, source, streaming,\n blocks,\n headings: previous && headings.length === previous.headings.length && headings.every((heading, index) => {\n const old = previous.headings[index];\n return heading.id === old.id && heading.text === old.text && heading.level === old.level && heading.blockId === old.blockId && heading.range.start === old.range.start && heading.range.end === old.range.end;\n }) ? previous.headings : headings,\n definitions, footnotes, footnoteOrder, annotations: [...annotations.values()], occurrences,\n diagnostics: parsed.diagnostics,\n metrics: { parsedCharacters, reusedBlocks: reused, parsedBlocks: parsed.nodes.length, fullParse: start === 0, reason },\n };\n for (const listener of this.listeners) listener();\n return this.snapshot;\n }\n}\n\nexport function createDocument(source = '', options: DocumentOptions = {}): DocumentEngine { return new DocumentEngine(source, options); }\n\nexport function replaceExtension<T extends SyntaxExtension>(extensions: readonly T[], replacement: T): T[] {\n const exists = extensions.some(extension => extension.name === replacement.name);\n return exists ? extensions.map(extension => extension.name === replacement.name ? replacement : extension) : [...extensions, replacement];\n}\n","import { decodeString } from 'micromark-util-decode-string';\nimport { intersects, rangeOf } from './tree';\nimport type { DocumentSnapshot, MarkdownNode, SelectionResult, SelectionSnapshot, SourceRange } from './types';\n\nexport interface TextMapping { starts: readonly number[]; ends: readonly number[]; exact: boolean }\n\n/** Align decoded text to original source, retaining escape/entity/CRLF boundaries. */\nexport function mapText(source: string, value: string, range: SourceRange, options: { escapes?: boolean } = {}): TextMapping {\n const raw = source.slice(range.start, range.end);\n const starts: number[] = [], ends: number[] = [];\n let rendered = 0, exact = true;\n for (let at = 0; at < raw.length && rendered < value.length;) {\n let length = 1, decoded = raw[at];\n if (options.escapes !== false && raw[at] === '\\\\' && /[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~]/.test(raw[at + 1] ?? '')) { length = 2; decoded = raw[at + 1]; }\n else if (raw[at] === '&') {\n const entity = /^&(?:#x[\\da-f]+|#\\d+|[a-z][\\da-z]+);/i.exec(raw.slice(at));\n if (entity) { const result = decodeString(entity[0]); if (result !== entity[0]) { length = entity[0].length; decoded = result; } }\n } else if (raw[at] === '\\r') { length = raw[at + 1] === '\\n' ? 2 : 1; decoded = '\\n'; }\n if (value.startsWith(decoded, rendered)) {\n for (let unit = 0; unit < decoded.length; unit++) { starts.push(range.start + at); ends.push(range.start + at + length); }\n rendered += decoded.length;\n } else if (!/[\\s>]/.test(decoded)) exact = false;\n at += length;\n }\n if (rendered !== value.length) exact = false;\n while (starts.length < value.length) { starts.push(range.start); ends.push(range.end); }\n return { starts, ends, exact };\n}\n\nexport function selectionFromRange(document: DocumentSnapshot, raw: SourceRange, options: { text?: string; quality?: SelectionSnapshot['quality']; settled?: boolean } = {}): SelectionSnapshot {\n const initial = { start: Math.max(0, raw.start), end: Math.min(document.source.length, raw.end) };\n const syntax = { ...initial };\n const containers = new Set(['strong', 'emphasis', 'delete', 'link', 'linkReference', 'heading', 'listItem', 'blockquote']);\n const source = document.source;\n const whitespace = (start: number, end: number) => !source.slice(start, end).trim();\n // Walk boundary ancestors inside-out. Each edge absorbs only its adjacent\n // delimiter, never the unselected words inside an ancestor. Custom component\n // tags remain boundaries; their Markdown children still participate normally.\n function expand(node: MarkdownNode) {\n const range = rangeOf(node);\n if (!intersects(range, syntax) || range.start >= syntax.start && range.end <= syntax.end) return;\n node.children?.forEach(expand);\n let content: SourceRange | undefined;\n if (containers.has(node.type) && node.children?.length) {\n content = { start: rangeOf(node.children[0]).start, end: rangeOf(node.children.at(-1)!).end };\n } else if (node.type === 'inlineCode' || node.type === 'inlineMath') {\n const length = (node.type === 'inlineCode' ? /^`+/ : /^\\$+/).exec(source.slice(range.start, range.end))?.[0].length ?? 0;\n content = { start: range.start + length, end: range.end - length };\n } else if (node.type === 'code' || node.type === 'math') {\n const raw = source.slice(range.start, range.end);\n const opening = /^[ \\t]*(`{3,}|~{3,}|\\${2,})[^\\r\\n]*(?:\\r\\n|\\r|\\n)/.exec(raw);\n if (opening) {\n const fence = opening[1];\n const closing = /(?:\\r\\n|\\r|\\n)[ \\t]*(`+|~+|\\$+)[ \\t]*$/.exec(raw);\n const closed = closing && closing[1][0] === fence[0] && closing[1].length >= fence.length;\n content = { start: range.start + opening[0].length, end: closed ? range.start + closing.index : range.end };\n }\n }\n if (content) {\n if (syntax.start > range.start && syntax.start < range.end && (syntax.start <= content.start || whitespace(content.start, syntax.start))) syntax.start = range.start;\n if (syntax.end < range.end && syntax.end > range.start && (syntax.end >= content.end || whitespace(syntax.end, content.end))) syntax.end = range.end;\n }\n if (node.type === 'blockquote') {\n // Continuation lines have their own quote prefixes, independent of the\n // paragraph's first line. Do not consume earlier, unselected quote text.\n const line = Math.max(range.start, source.lastIndexOf('\\n', syntax.start - 1) + 1);\n if (/^[ \\t]*(?:>[ \\t]*)+$/.test(source.slice(line, syntax.start))) syntax.start = line;\n }\n }\n let lo = 0, hi = document.blocks.length;\n while (lo < hi) { const mid = (lo + hi) >>> 1; if (document.blocks[mid].range.end <= initial.start) lo = mid + 1; else hi = mid; }\n const selectedBlocks = [];\n for (let index = lo; index < document.blocks.length && document.blocks[index].range.start < initial.end; index++) {\n const block = document.blocks[index]; selectedBlocks.push(block); expand(block.node);\n }\n const blockRanges: SourceRange[] = [];\n const blockTypes = new Set(['paragraph', 'heading', 'code', 'math', 'table', 'listItem', 'thematicBreak', 'html']);\n function collect(node: MarkdownNode) {\n const range = rangeOf(node);\n if (!intersects(range, initial)) return;\n if (blockTypes.has(node.type) || node.type === 'component' && !node.inline) { blockRanges.push(range); return; }\n node.children?.forEach(collect);\n }\n selectedBlocks.forEach(block => collect(block.node));\n const result = (ranges: SourceRange[]): SelectionResult => ({ ranges, sourceText: ranges.map(range => document.source.slice(range.start, range.end)).join('\\n\\n') });\n return {\n documentId: document.id, revision: document.revision, text: options.text ?? document.source.slice(initial.start, initial.end),\n quality: options.quality ?? 'exact', settled: options.settled ?? true,\n raw: result([initial]), syntax: result([syntax]), blocks: result(blockRanges.length ? blockRanges : [initial]),\n };\n}\n","import type { Annotation, AnnotationAnchor, AnnotationOccurrence, DocumentSnapshot, HighlightData, MarkdownNode, SourceRange } from './types';\nimport { intersects, rangeOf } from './tree';\n\nexport const defaultHighlight: Readonly<HighlightData> = { color: '#F2C744', style: 'background' };\nexport const sameRange = (a: SourceRange, b: SourceRange) => a.start === b.start && a.end === b.end;\n\n/** Embedded references quote their nearest text block; keep the marker's own\n * range intact for source mapping, insertion and selection. */\nexport function annotationReferenceRange(document: DocumentSnapshot, occurrence: AnnotationOccurrence): SourceRange {\n if (occurrence.referenceRange) return occurrence.referenceRange;\n if (!occurrence.embedded) return occurrence.range;\n let reference = occurrence.range;\n const visit = (node: MarkdownNode) => {\n const range = rangeOf(node);\n if (!intersects(range, occurrence.range)) return;\n if (['paragraph', 'heading', 'listItem', 'tableCell'].includes(node.type)) reference = range;\n node.children?.forEach(visit);\n };\n for (const block of document.blocks) if (intersects(block.range, occurrence.range)) visit(block.node);\n return reference;\n}\n\n/** Resolve persisted anchors once against the current source. */\nexport function resolveAnnotationAnchors(annotation: Annotation, document: DocumentSnapshot): AnnotationAnchor[] {\n return (annotation.anchors ?? (annotation.range ? [{ range: annotation.range }] : [])).flatMap(anchor => {\n if (anchor.documentId && anchor.documentId !== document.id) return [];\n let range = anchor.range;\n if (anchor.quote && document.source.slice(range.start, range.end) !== anchor.quote) {\n const start = document.source.indexOf(anchor.quote);\n if (start < 0 || document.source.indexOf(anchor.quote, start + 1) >= 0) return [];\n range = { start, end: start + anchor.quote.length };\n } else if (anchor.revision !== undefined && anchor.revision !== document.revision && !anchor.quote) return [];\n return range.start >= 0 && range.end <= document.source.length && range.start <= range.end ? [{ ...anchor, range }] : [];\n });\n}\n"],"mappings":"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","names":["fence","tail","decodeString","decodeString","raw"]}
@@ -0,0 +1,179 @@
1
+ import {
2
+ intersects
3
+ } from "./chunk-FJZCQY2S.js";
4
+
5
+ // src/react/source-geometry.ts
6
+ var measurementRanges = /* @__PURE__ */ new WeakMap();
7
+ function measurementRange(document) {
8
+ let range = measurementRanges.get(document);
9
+ if (!range) {
10
+ range = document.createRange();
11
+ measurementRanges.set(document, range);
12
+ }
13
+ return range;
14
+ }
15
+ function flowOf(element, container) {
16
+ const known = element.closest("pre,p,figcaption,li,th,td,h1,h2,h3,h4,h5,h6,.limr-choice-text,.limr-definition-title,.limr-question-title,.limr-block-content");
17
+ return known && container.contains(known) ? known : element.closest("[data-limr-block]") ?? container;
18
+ }
19
+ function leavesIn(block, runtime) {
20
+ const result = [];
21
+ visitLeaves(block, runtime, (leaf) => {
22
+ result.push(leaf);
23
+ return false;
24
+ });
25
+ return result;
26
+ }
27
+ function visitLeaves(block, runtime, accept, source, onBreak) {
28
+ runtime.prepareTextBindings(block);
29
+ const emit = (leaf) => (!source || intersects(leaf.range, source)) && accept(leaf);
30
+ const visit = (node, inherited) => {
31
+ if (node instanceof HTMLElement) {
32
+ if (node !== block && node.hasAttribute("data-limr-document") || node.hasAttribute("inert")) return false;
33
+ const marker = node.dataset.limrMarker;
34
+ const atomic = node.dataset.limrAtomic;
35
+ if (marker || atomic) {
36
+ const image = node.dataset.limrMedia === "image";
37
+ return emit({ node, kind: marker ? "marker" : image ? "image" : atomic === "block" ? "block" : "inline", range: { start: Number(node.dataset.sourceStart), end: Number(node.dataset.sourceEnd) }, flow: image ? node : flowOf(node, runtime.content), offset: 0 });
38
+ }
39
+ if (node.hasAttribute("data-limr-ignore")) return false;
40
+ if (onBreak && node.hasAttribute("data-limr-break")) onBreak({ start: Number(node.dataset.sourceStart), end: Number(node.dataset.sourceEnd) });
41
+ const binding = runtime.bindings.get(node);
42
+ if (source && binding && !intersects(binding.range, source)) return false;
43
+ if (binding) inherited = { binding, offset: 0 };
44
+ }
45
+ if (node.nodeType === Node.TEXT_NODE) {
46
+ const binding = runtime.bindings.get(node) ?? inherited?.binding;
47
+ const offset = runtime.bindings.has(node) ? 0 : inherited?.offset ?? 0;
48
+ const length = node.textContent?.length ?? 0;
49
+ if (inherited) inherited.offset += length;
50
+ if (binding?.resolve && length) return emit({ node, kind: "text", range: { start: binding.resolve(offset, "start"), end: binding.resolve(offset + length, "end") }, flow: flowOf(node.parentElement, runtime.content), binding, offset });
51
+ return false;
52
+ }
53
+ for (const child of node.childNodes) if (visit(child, inherited)) return true;
54
+ return false;
55
+ };
56
+ return visit(block);
57
+ }
58
+ function textRange(leaf, source, viewport) {
59
+ const node = leaf.node, length = node.length;
60
+ const resolve = leaf.binding.resolve;
61
+ let lo = 0, hi = length;
62
+ while (lo < hi) {
63
+ const mid = lo + hi >>> 1;
64
+ if (resolve(leaf.offset + mid + 1, "end") <= source.start) lo = mid + 1;
65
+ else hi = mid;
66
+ }
67
+ let start = lo;
68
+ lo = start;
69
+ hi = length;
70
+ while (lo < hi) {
71
+ const mid = lo + hi >>> 1;
72
+ if (resolve(leaf.offset + mid, "start") < source.end) lo = mid + 1;
73
+ else hi = mid;
74
+ }
75
+ if (start === lo) return null;
76
+ let end = lo;
77
+ const range = measurementRange(node.ownerDocument);
78
+ if (viewport && end - start > 1024) {
79
+ range.setStart(node, start);
80
+ range.setEnd(node, end);
81
+ const box = range.getBoundingClientRect();
82
+ if (box.height > viewport.bottom - viewport.top + 80) {
83
+ lo = start;
84
+ hi = end;
85
+ while (lo < hi) {
86
+ const mid = lo + hi >>> 1;
87
+ range.setStart(node, mid);
88
+ range.setEnd(node, mid + 1);
89
+ if (range.getBoundingClientRect().bottom < viewport.top) lo = mid + 1;
90
+ else hi = mid;
91
+ }
92
+ start = lo;
93
+ hi = end;
94
+ while (lo < hi) {
95
+ const mid = lo + hi >>> 1;
96
+ range.setStart(node, mid);
97
+ range.setEnd(node, mid + 1);
98
+ if (range.getBoundingClientRect().top <= viewport.bottom) lo = mid + 1;
99
+ else hi = mid;
100
+ }
101
+ end = lo;
102
+ }
103
+ }
104
+ if (start === end) return null;
105
+ range.setStart(node, start);
106
+ range.setEnd(node, end);
107
+ return range;
108
+ }
109
+ function atomicSelectionText(runtime, ranges) {
110
+ const document = runtime.document.getSnapshot();
111
+ const selected = (range) => ranges.some((source) => intersects(source, range));
112
+ const blocks = document.blocks.filter((block) => selected(block.range)).map((block) => runtime.blocks.get(block.id)).filter((element) => !!element);
113
+ const hasAtomic = blocks.some((block) => [block, ...block.querySelectorAll("[data-limr-atomic]")].some((element) => element.hasAttribute("data-limr-atomic") && selected({ start: Number(element.dataset.sourceStart), end: Number(element.dataset.sourceEnd) })));
114
+ if (!hasAtomic) return;
115
+ const paragraphs = [];
116
+ for (const block of blocks) {
117
+ const parts = [];
118
+ let previousFlow;
119
+ visitLeaves(block, runtime, (leaf) => {
120
+ if (leaf.kind === "marker" || !selected(leaf.range)) return false;
121
+ const text = leaf.kind !== "text" ? document.source.slice(leaf.range.start, leaf.range.end) : ranges.filter((range) => intersects(range, leaf.range)).map((range) => textRange(leaf, range)?.toString() ?? "").join("");
122
+ if (!text) return false;
123
+ if (previousFlow && previousFlow !== leaf.flow) parts.push(previousFlow.matches("th,td") && leaf.flow.matches("th,td") && previousFlow.parentElement === leaf.flow.parentElement ? " " : "\n");
124
+ parts.push(text);
125
+ previousFlow = leaf.flow;
126
+ return false;
127
+ }, void 0, (range) => {
128
+ if (selected(range)) parts.push("\n");
129
+ });
130
+ if (parts.length) paragraphs.push(parts.join(""));
131
+ }
132
+ return paragraphs.join("\n\n");
133
+ }
134
+ function sourceRangeStartRect(runtime, source) {
135
+ for (const block of runtime.document.getSnapshot().blocks) {
136
+ if (!intersects(block.range, source)) continue;
137
+ const element = runtime.blocks.get(block.id);
138
+ if (!element) continue;
139
+ let found = null;
140
+ visitLeaves(element, runtime, (leaf) => {
141
+ if (leaf.kind === "marker") return false;
142
+ if (leaf.kind === "text") {
143
+ const range = textRange(leaf, source);
144
+ if (!range) return false;
145
+ const node = leaf.node, end = range.endOffset;
146
+ for (let start = range.startOffset; start < end; ) {
147
+ const next = Math.min(end, start + (node.data.codePointAt(start) > 65535 ? 2 : 1));
148
+ range.setStart(node, start);
149
+ range.setEnd(node, next);
150
+ const rect = range.getBoundingClientRect();
151
+ if (rect.width && rect.height) {
152
+ found = rect;
153
+ return true;
154
+ }
155
+ start = next;
156
+ }
157
+ } else {
158
+ const node = leaf.node;
159
+ const rect = (node.querySelector(leaf.kind === "image" ? "img" : "[data-limr-selection-surface]") ?? node).getBoundingClientRect();
160
+ if (rect.width && rect.height) {
161
+ found = rect;
162
+ return true;
163
+ }
164
+ }
165
+ return false;
166
+ }, source);
167
+ if (found) return found;
168
+ }
169
+ return null;
170
+ }
171
+
172
+ export {
173
+ measurementRange,
174
+ leavesIn,
175
+ textRange,
176
+ atomicSelectionText,
177
+ sourceRangeStartRect
178
+ };
179
+ //# sourceMappingURL=chunk-BVHHOVMT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/source-geometry.ts"],"sourcesContent":["import type { SourceRange } from '../core';\nimport { intersects } from '../core/tree';\nimport type { ReaderRuntime, SourceBinding } from './runtime';\n\nexport interface Leaf {\n node: Text | HTMLElement;\n kind: 'text' | 'marker' | 'inline' | 'block' | 'image';\n range: SourceRange;\n flow: HTMLElement;\n binding?: SourceBinding;\n offset: number;\n}\nexport interface Viewport { top: number; bottom: number; left: number; right: number }\n\nconst measurementRanges = new WeakMap<Document, Range>();\n/** Synchronous scratch range, never retained as a selection. Reusing it avoids\n * thousands of live browser ranges updating during subsequent DOM mutations. */\nexport function measurementRange(document: Document): Range {\n let range = measurementRanges.get(document);\n if (!range) { range = document.createRange(); measurementRanges.set(document, range); }\n return range;\n}\n\nfunction flowOf(element: HTMLElement, container: HTMLElement): HTMLElement {\n const known = element.closest<HTMLElement>('pre,p,figcaption,li,th,td,h1,h2,h3,h4,h5,h6,.limr-choice-text,.limr-definition-title,.limr-question-title,.limr-block-content');\n return known && container.contains(known) ? known : element.closest<HTMLElement>('[data-limr-block]') ?? container;\n}\n\nexport function leavesIn(block: HTMLElement, runtime: ReaderRuntime): Leaf[] {\n const result: Leaf[] = [];\n visitLeaves(block, runtime, leaf => { result.push(leaf); return false; });\n return result;\n}\n\n/** Short-circuit a source lookup without building every KP line's leaf list.\n * Full-range paint still visits all leaves; card anchors stop at the first ink. */\nfunction visitLeaves(block: HTMLElement, runtime: ReaderRuntime, accept: (leaf: Leaf) => boolean, source?: SourceRange, onBreak?: (range: SourceRange) => void) {\n runtime.prepareTextBindings(block);\n const emit = (leaf: Leaf) => (!source || intersects(leaf.range, source)) && accept(leaf);\n const visit = (node: Node, inherited?: { binding: SourceBinding; offset: number }): boolean => {\n if (node instanceof HTMLElement) {\n if (node !== block && node.hasAttribute('data-limr-document') || node.hasAttribute('inert')) return false;\n const marker = node.dataset.limrMarker;\n const atomic = node.dataset.limrAtomic;\n if (marker || atomic) {\n const image = node.dataset.limrMedia === 'image';\n return emit({ node, kind: marker ? 'marker' : image ? 'image' : atomic === 'block' ? 'block' : 'inline', range: { start: Number(node.dataset.sourceStart), end: Number(node.dataset.sourceEnd) }, flow: image ? node : flowOf(node, runtime.content!), offset: 0 });\n }\n if (node.hasAttribute('data-limr-ignore')) return false;\n if (onBreak && node.hasAttribute('data-limr-break')) onBreak({ start: Number(node.dataset.sourceStart), end: Number(node.dataset.sourceEnd) });\n const binding = runtime.bindings.get(node);\n if (source && binding && !intersects(binding.range, source)) return false;\n if (binding) inherited = { binding, offset: 0 };\n }\n if (node.nodeType === Node.TEXT_NODE) {\n const binding = runtime.bindings.get(node) ?? inherited?.binding;\n const offset = runtime.bindings.has(node) ? 0 : inherited?.offset ?? 0;\n const length = node.textContent?.length ?? 0;\n if (inherited) inherited.offset += length;\n if (binding?.resolve && length) return emit({ node: node as Text, kind: 'text', range: { start: binding.resolve(offset, 'start'), end: binding.resolve(offset + length, 'end') }, flow: flowOf(node.parentElement!, runtime.content!), binding, offset });\n return false;\n }\n for (const child of node.childNodes) if (visit(child, inherited)) return true;\n return false;\n };\n return visit(block);\n}\n\nexport function textRange(leaf: Leaf, source: SourceRange, viewport?: Viewport): Range | null {\n const node = leaf.node as Text, length = node.length;\n const resolve = leaf.binding!.resolve!;\n // Binary searches preserve decoded entities, surrogate pairs and source gaps.\n let lo = 0, hi = length;\n while (lo < hi) { const mid = (lo + hi) >>> 1; if (resolve(leaf.offset + mid + 1, 'end') <= source.start) lo = mid + 1; else hi = mid; }\n let start = lo;\n lo = start; hi = length;\n while (lo < hi) { const mid = (lo + hi) >>> 1; if (resolve(leaf.offset + mid, 'start') < source.end) lo = mid + 1; else hi = mid; }\n if (start === lo) return null;\n let end = lo;\n const range = measurementRange(node.ownerDocument);\n // A single unwrapped text node can contain a book or a large code fence.\n // Bound its native Range before requesting line rectangles.\n if (viewport && end - start > 1024) {\n range.setStart(node, start); range.setEnd(node, end);\n const box = range.getBoundingClientRect();\n if (box.height > viewport.bottom - viewport.top + 80) {\n lo = start; hi = end;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n range.setStart(node, mid); range.setEnd(node, mid + 1);\n if (range.getBoundingClientRect().bottom < viewport.top) lo = mid + 1; else hi = mid;\n }\n start = lo; hi = end;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n range.setStart(node, mid); range.setEnd(node, mid + 1);\n if (range.getBoundingClientRect().top <= viewport.bottom) lo = mid + 1; else hi = mid;\n }\n end = lo;\n }\n }\n if (start === end) return null;\n range.setStart(node, start); range.setEnd(node, end); return range;\n}\n\n/** Native math selections include KaTeX's presentation/accessibility trees,\n * sometimes just one glyph. Serialize selected atoms from source, preserving\n * surrounding rendered text and visual order instead of copying those trees. */\nexport function atomicSelectionText(runtime: ReaderRuntime, ranges: readonly SourceRange[]): string | undefined {\n const document = runtime.document.getSnapshot();\n const selected = (range: SourceRange) => ranges.some(source => intersects(source, range));\n const blocks = document.blocks.filter(block => selected(block.range)).map(block => runtime.blocks.get(block.id)).filter((element): element is HTMLElement => !!element);\n const hasAtomic = blocks.some(block => [block, ...block.querySelectorAll<HTMLElement>('[data-limr-atomic]')].some(element =>\n element.hasAttribute('data-limr-atomic') && selected({ start: Number(element.dataset.sourceStart), end: Number(element.dataset.sourceEnd) })));\n if (!hasAtomic) return;\n const paragraphs: string[] = [];\n for (const block of blocks) {\n const parts: string[] = []; let previousFlow: HTMLElement | undefined;\n visitLeaves(block, runtime, leaf => {\n if (leaf.kind === 'marker' || !selected(leaf.range)) return false;\n const text = leaf.kind !== 'text' ? document.source.slice(leaf.range.start, leaf.range.end) : ranges.filter(range => intersects(range, leaf.range)).map(range => textRange(leaf, range)?.toString() ?? '').join('');\n if (!text) return false;\n if (previousFlow && previousFlow !== leaf.flow) parts.push(previousFlow.matches('th,td') && leaf.flow.matches('th,td') && previousFlow.parentElement === leaf.flow.parentElement ? '\\t' : '\\n');\n parts.push(text); previousFlow = leaf.flow;\n return false;\n }, undefined, range => { if (selected(range)) parts.push('\\n'); });\n if (parts.length) paragraphs.push(parts.join(''));\n }\n return paragraphs.join('\\n\\n');\n}\n\n/** First rendered character of a source range, independent of its trailing marker. */\nexport function sourceRangeStartRect(runtime: ReaderRuntime, source: SourceRange): DOMRect | null {\n for (const block of runtime.document.getSnapshot().blocks) {\n if (!intersects(block.range, source)) continue;\n const element = runtime.blocks.get(block.id);\n if (!element) continue;\n let found: DOMRect | null = null;\n visitLeaves(element, runtime, leaf => {\n if (leaf.kind === 'marker') return false;\n if (leaf.kind === 'text') {\n const range = textRange(leaf, source);\n if (!range) return false;\n const node = leaf.node as Text, end = range.endOffset;\n // Measure a character rather than the full range: book-length anchors\n // must not create thousands of line rectangles just to locate a card.\n for (let start = range.startOffset; start < end;) {\n const next = Math.min(end, start + (node.data.codePointAt(start)! > 0xffff ? 2 : 1));\n range.setStart(node, start); range.setEnd(node, next);\n const rect = range.getBoundingClientRect();\n if (rect.width && rect.height) { found = rect; return true; }\n start = next;\n }\n } else {\n const node = leaf.node as HTMLElement;\n const rect = (node.querySelector(leaf.kind === 'image' ? 'img' : '[data-limr-selection-surface]') ?? node).getBoundingClientRect();\n if (rect.width && rect.height) { found = rect; return true; }\n }\n return false;\n }, source);\n if (found) return found;\n }\n return null;\n}\n\n"],"mappings":"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","names":[]}
@@ -0,0 +1,155 @@
1
+ // src/core/tree.ts
2
+ function walk(node, visit, parent) {
3
+ visit(node, parent);
4
+ for (const child of node.children ?? []) walk(child, visit, node);
5
+ }
6
+ function textContent(node) {
7
+ if (node.type === "image") return String(node.alt ?? "");
8
+ return node.value ?? node.children?.map(textContent).join("") ?? "";
9
+ }
10
+ function rangeOf(node) {
11
+ return { start: node.position?.start.offset ?? 0, end: node.position?.end.offset ?? 0 };
12
+ }
13
+ function intersects(a, b) {
14
+ return a.start < b.end && b.start < a.end;
15
+ }
16
+ function lineStarts(source) {
17
+ const result = [0];
18
+ for (let i = 0; i < source.length; i++) {
19
+ if (source[i] === "\r") {
20
+ if (source[i + 1] === "\n") i++;
21
+ result.push(i + 1);
22
+ } else if (source[i] === "\n") result.push(i + 1);
23
+ }
24
+ return result;
25
+ }
26
+ function sourcePoint(offset, lines) {
27
+ let lo = 0, hi = lines.length;
28
+ while (lo + 1 < hi) {
29
+ const mid = lo + hi >>> 1;
30
+ if (lines[mid] <= offset) lo = mid;
31
+ else hi = mid;
32
+ }
33
+ return { offset, line: lo + 1, column: offset - lines[lo] + 1 };
34
+ }
35
+ function slugify(text) {
36
+ return text.toLowerCase().trim().replace(/[^\p{L}\p{N}\s_-]/gu, "").replace(/[\s_]+/g, "-").replace(/^-+|-+$/g, "") || "section";
37
+ }
38
+ function safeUrl(value, image = false) {
39
+ if (typeof value !== "string") return void 0;
40
+ const normalized = value.trim().replace(/[\u0000-\u0020\u007f]/g, "");
41
+ if (/^(?:https?:|mailto:|tel:)/i.test(normalized) || !/^[a-z][a-z\d+.-]*:/i.test(normalized)) return value;
42
+ if (image && /^data:image\/(?:png|gif|jpe?g|webp|avif);base64,/i.test(normalized)) return value;
43
+ return void 0;
44
+ }
45
+
46
+ // src/core/knuth-plass.ts
47
+ var scale = 65536;
48
+ function texBadness(amount, available) {
49
+ const t = Math.round(Math.abs(amount) * scale), s = Math.round(available * scale);
50
+ if (!t) return 0;
51
+ if (s <= 0) return 1e4;
52
+ const r = t <= 7230584 ? Math.floor(t * 297 / s) : s >= 1663497 ? Math.floor(t / Math.floor(s / 297)) : t;
53
+ return r > 1290 ? 1e4 : Math.floor((r * r * r + 131072) / 262144);
54
+ }
55
+ function knuthPlass(items, lengths, options = {}) {
56
+ return prepareKnuthPlass(items)(lengths, options);
57
+ }
58
+ function prepareKnuthPlass(items) {
59
+ const n = items.length;
60
+ const widths = new Float64Array(n + 1), stretches = new Float64Array(n + 1), shrinks = new Float64Array(n + 1), infinite = new Uint32Array(n + 1);
61
+ const next = new Uint32Array(n + 1);
62
+ next[n] = n;
63
+ let monotonic = true;
64
+ for (let i = 0; i < n; i++) {
65
+ const item = items[i];
66
+ widths[i + 1] = widths[i] + (item.type === "penalty" ? 0 : item.width);
67
+ stretches[i + 1] = stretches[i] + (item.type === "glue" ? item.stretch : 0);
68
+ shrinks[i + 1] = shrinks[i] + (item.type === "glue" ? item.shrink : 0);
69
+ infinite[i + 1] = infinite[i] + (item.type === "glue" && item.infinite ? 1 : 0);
70
+ if (item.width < 0 || item.type === "glue" && (item.shrink < 0 || item.stretch < 0 || item.width < item.shrink)) monotonic = false;
71
+ }
72
+ for (let i = n - 1; i >= 0; i--) next[i] = items[i].type === "box" || items[i].type === "penalty" && items[i].penalty >= 1e4 ? i : next[i + 1];
73
+ return (lengths, options = {}) => {
74
+ if (!n) return { lines: [], demerits: 0, pass: "pretolerance" };
75
+ const varying = typeof lengths !== "number", looseness = options.looseness ?? 0;
76
+ const lineWidth = (line) => typeof lengths === "number" ? lengths : lengths[Math.min(line, lengths.length - 1)];
77
+ const linePenalty = options.linePenalty ?? 10, adjacent = options.adjacentDemerits ?? 1e4;
78
+ const pass = (threshold, hyphens, emergency2, final) => {
79
+ let active = [{ at: -1, start: next[0], line: 0, fitness: 1, flagged: false, demerits: 0, ratio: 0 }];
80
+ for (let b = 0; b < n; b++) {
81
+ const item = items[b];
82
+ if (!(item.type === "glue" && b > 0 && items[b - 1].type === "box") && !(item.type === "penalty" && item.penalty < 1e4 && (hyphens || !item.automatic))) continue;
83
+ const forced = item.type === "penalty" && item.penalty <= -1e4;
84
+ const best2 = /* @__PURE__ */ new Map(), survivors = [];
85
+ let fallback;
86
+ for (const a of active) {
87
+ const start = Math.min(a.start, b), natural = widths[b] - widths[start] + (item.type === "penalty" ? item.width : 0);
88
+ const shrink = shrinks[b] - shrinks[start], stretch = stretches[b] - stretches[start] + emergency2;
89
+ const difference = lineWidth(a.line) - natural;
90
+ const fil = infinite[b] > infinite[start];
91
+ const badness = difference < -shrink ? 10001 : difference > 0 && fil ? 0 : texBadness(difference, difference > 0 ? stretch : shrink);
92
+ const fitness = difference < 0 ? badness > 12 ? 0 : 1 : badness > 99 ? 3 : badness > 12 ? 2 : 1;
93
+ const penalty = item.type === "penalty" ? item.penalty : 0;
94
+ const flagged = item.type === "penalty" && !!item.flagged;
95
+ let cost = Math.min(1e4, Math.abs(linePenalty + badness)) ** 2;
96
+ if (penalty >= 0) cost += penalty * penalty;
97
+ else if (penalty > -1e4) cost -= penalty * penalty;
98
+ if (a.flagged && b === n - 1) cost += options.finalHyphenDemerits ?? 5e3;
99
+ else if (a.flagged && flagged) cost += options.doubleHyphenDemerits ?? 1e4;
100
+ if (Math.abs(fitness - a.fitness) > 1) cost += adjacent;
101
+ const outputRatio = difference === 0 || difference > 0 && fil ? 0 : difference / (difference > 0 ? stretches[b] - stretches[start] : shrink);
102
+ const candidate = { at: b, start: next[Math.min(n, b + 1)], line: a.line + 1, fitness, flagged, demerits: a.demerits + cost, ratio: Number.isFinite(outputRatio) ? Math.max(-1, outputRatio) : 0, previous: a };
103
+ if (badness <= threshold) {
104
+ const key = (looseness ? candidate.line : varying ? Math.min(candidate.line, lengths.length - 1) : 0) * 4 + fitness;
105
+ if (!best2.has(key) || best2.get(key).demerits > candidate.demerits) best2.set(key, candidate);
106
+ }
107
+ if (!fallback || candidate.demerits < fallback.demerits) fallback = candidate;
108
+ if (!forced && (!monotonic || widths[b] - widths[start] - shrink <= lineWidth(a.line))) survivors.push(a);
109
+ }
110
+ if (final && !best2.size && !survivors.length && fallback) {
111
+ fallback.demerits = fallback.previous.demerits;
112
+ best2.set(fallback.fitness, fallback);
113
+ }
114
+ active = [...survivors, ...best2.values()];
115
+ if (!active.length) return;
116
+ }
117
+ const endings = active.filter((a) => a.at === n - 1);
118
+ const best = endings.reduce((best2, a) => !best2 || a.demerits < best2.demerits ? a : best2, void 0);
119
+ if (!best || !looseness) return best;
120
+ const desired = best.line + looseness;
121
+ const chosen = endings.reduce((chosen2, a) => Math.abs(a.line - desired) < Math.abs(chosen2.line - desired) || Math.abs(a.line - desired) === Math.abs(chosen2.line - desired) && a.demerits < chosen2.demerits ? a : chosen2, best);
122
+ return final || chosen.line === desired ? chosen : void 0;
123
+ };
124
+ const emergency = options.emergencyStretch ?? 16;
125
+ const passes = [
126
+ { name: "pretolerance", threshold: options.pretolerance ?? 100, hyphens: false, emergency: 0, final: false },
127
+ { name: "tolerance", threshold: options.tolerance ?? 200, hyphens: true, emergency: 0, final: emergency <= 0 },
128
+ { name: "emergency", threshold: options.tolerance ?? 200, hyphens: true, emergency, final: true }
129
+ ];
130
+ for (const attempt of passes) {
131
+ if (attempt.threshold < 0 || attempt.name === "emergency" && !attempt.emergency) continue;
132
+ const result = pass(Math.min(1e4, attempt.threshold), attempt.hyphens, attempt.emergency, attempt.final);
133
+ if (!result) continue;
134
+ const lines = [];
135
+ for (let at = result; at.previous; at = at.previous) lines.push({ index: at.at, start: at.previous.start, ratio: at.ratio, fitness: at.fitness });
136
+ return { lines: lines.reverse(), demerits: result.demerits, pass: attempt.name };
137
+ }
138
+ return { lines: [], demerits: Infinity, pass: "final" };
139
+ };
140
+ }
141
+
142
+ export {
143
+ walk,
144
+ textContent,
145
+ rangeOf,
146
+ intersects,
147
+ lineStarts,
148
+ sourcePoint,
149
+ slugify,
150
+ safeUrl,
151
+ texBadness,
152
+ knuthPlass,
153
+ prepareKnuthPlass
154
+ };
155
+ //# sourceMappingURL=chunk-FJZCQY2S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/tree.ts","../src/core/knuth-plass.ts"],"sourcesContent":["import type { MarkdownNode, SourcePoint, SourceRange } from './types';\n\nexport function walk(node: MarkdownNode, visit: (node: MarkdownNode, parent?: MarkdownNode) => void, parent?: MarkdownNode): void {\n visit(node, parent);\n for (const child of node.children ?? []) walk(child, visit, node);\n}\nexport function textContent(node: MarkdownNode): string {\n if (node.type === 'image') return String(node.alt ?? '');\n return node.value ?? node.children?.map(textContent).join('') ?? '';\n}\nexport function rangeOf(node: MarkdownNode): SourceRange {\n return { start: node.position?.start.offset ?? 0, end: node.position?.end.offset ?? 0 };\n}\nexport function intersects(a: SourceRange, b: SourceRange): boolean { return a.start < b.end && b.start < a.end; }\nexport function lineStarts(source: string): number[] {\n const result = [0];\n for (let i = 0; i < source.length; i++) {\n if (source[i] === '\\r') { if (source[i + 1] === '\\n') i++; result.push(i + 1); }\n else if (source[i] === '\\n') result.push(i + 1);\n }\n return result;\n}\nexport function sourcePoint(offset: number, lines: readonly number[]): SourcePoint {\n let lo = 0, hi = lines.length;\n while (lo + 1 < hi) { const mid = (lo + hi) >>> 1; if (lines[mid] <= offset) lo = mid; else hi = mid; }\n return { offset, line: lo + 1, column: offset - lines[lo] + 1 };\n}\nexport function slugify(text: string): string {\n return text.toLowerCase().trim().replace(/[^\\p{L}\\p{N}\\s_-]/gu, '').replace(/[\\s_]+/g, '-').replace(/^-+|-+$/g, '') || 'section';\n}\nexport function safeUrl(value: unknown, image = false): string | undefined {\n if (typeof value !== 'string') return undefined;\n const normalized = value.trim().replace(/[\\u0000-\\u0020\\u007f]/g, '');\n if (/^(?:https?:|mailto:|tel:)/i.test(normalized) || !/^[a-z][a-z\\d+.-]*:/i.test(normalized)) return value;\n if (image && /^data:image\\/(?:png|gif|jpe?g|webp|avif);base64,/i.test(normalized)) return value;\n return undefined;\n}\n","/** TeX82's paragraph model (tex.web, sections 815–873): boxes, glue,\n * discretionary penalties, four fitness classes and a minimum-demerit path.\n * Widths are converted to scaled units for TeX's integer badness calculation. */\nexport type LineItem = { type: 'box'; width: number }\n | { type: 'glue'; width: number; stretch: number; shrink: number; infinite?: boolean }\n | { type: 'penalty'; width: number; penalty: number; flagged?: boolean; automatic?: boolean };\nexport interface KnuthPlassOptions {\n pretolerance?: number;\n tolerance?: number;\n linePenalty?: number;\n hyphenPenalty?: number;\n adjacentDemerits?: number;\n doubleHyphenDemerits?: number;\n finalHyphenDemerits?: number;\n /** Extra stretch in CSS pixels in the emergency pass, as in TeX. */\n emergencyStretch?: number;\n looseness?: number;\n /** Default: Knuth–Liang en-US patterns. Return pieces that join to the word. */\n hyphenate?: false | ((word: string) => readonly string[]);\n}\nexport interface LineBreak { index: number; start: number; ratio: number; fitness: number }\nexport interface ParagraphLayout { lines: LineBreak[]; demerits: number; pass: 'pretolerance' | 'tolerance' | 'emergency' | 'final' }\nconst scale = 65536;\n/** The integer approximation used by TeX, including its saturation at 10000. */\nexport function texBadness(amount: number, available: number): number {\n const t = Math.round(Math.abs(amount) * scale), s = Math.round(available * scale);\n if (!t) return 0;\n if (s <= 0) return 10000;\n const r = t <= 7230584 ? Math.floor(t * 297 / s) : s >= 1663497 ? Math.floor(t / Math.floor(s / 297)) : t;\n return r > 1290 ? 10000 : Math.floor((r * r * r + 131072) / 262144);\n}\ninterface Active { at: number; start: number; line: number; fitness: number; flagged: boolean; demerits: number; ratio: number; previous?: Active }\n\n/** Prefix sums and safe active-node pruning remove repeated line scans. With\n * constant line lengths and zero looseness, equal fitness is an exact shared\n * state: future cost is independent of line count. No beam or word limit. */\nexport function knuthPlass(items: readonly LineItem[], lengths: number | readonly number[], options: KnuthPlassOptions = {}): ParagraphLayout {\n return prepareKnuthPlass(items)(lengths, options);\n}\n\n/** Retains width/stretch prefix sums across responsive layouts of the same text. */\nexport function prepareKnuthPlass(items: readonly LineItem[]): (lengths: number | readonly number[], options?: KnuthPlassOptions) => ParagraphLayout {\n const n = items.length;\n const widths = new Float64Array(n + 1), stretches = new Float64Array(n + 1), shrinks = new Float64Array(n + 1), infinite = new Uint32Array(n + 1);\n const next = new Uint32Array(n + 1); next[n] = n;\n let monotonic = true;\n for (let i = 0; i < n; i++) {\n const item = items[i];\n widths[i + 1] = widths[i] + (item.type === 'penalty' ? 0 : item.width);\n stretches[i + 1] = stretches[i] + (item.type === 'glue' ? item.stretch : 0);\n shrinks[i + 1] = shrinks[i] + (item.type === 'glue' ? item.shrink : 0);\n infinite[i + 1] = infinite[i] + (item.type === 'glue' && item.infinite ? 1 : 0);\n if (item.width < 0 || item.type === 'glue' && (item.shrink < 0 || item.stretch < 0 || item.width < item.shrink)) monotonic = false;\n }\n for (let i = n - 1; i >= 0; i--) next[i] = items[i].type === 'box' || items[i].type === 'penalty' && (items[i] as Extract<LineItem, { type: 'penalty' }>).penalty >= 10000 ? i : next[i + 1];\n return (lengths, options = {}) => {\n if (!n) return { lines: [], demerits: 0, pass: 'pretolerance' };\n const varying = typeof lengths !== 'number', looseness = options.looseness ?? 0;\n const lineWidth = (line: number) => typeof lengths === 'number' ? lengths : lengths[Math.min(line, lengths.length - 1)];\n const linePenalty = options.linePenalty ?? 10, adjacent = options.adjacentDemerits ?? 10000;\n const pass = (threshold: number, hyphens: boolean, emergency: number, final: boolean): Active | undefined => {\n let active: Active[] = [{ at: -1, start: next[0], line: 0, fitness: 1, flagged: false, demerits: 0, ratio: 0 }];\n for (let b = 0; b < n; b++) {\n const item = items[b];\n if (!(item.type === 'glue' && b > 0 && items[b - 1].type === 'box') && !(item.type === 'penalty' && item.penalty < 10000 && (hyphens || !item.automatic))) continue;\n const forced = item.type === 'penalty' && item.penalty <= -10000;\n const best = new Map<number, Active>(), survivors: Active[] = [];\n let fallback: Active | undefined;\n for (const a of active) {\n const start = Math.min(a.start, b), natural = widths[b] - widths[start] + (item.type === 'penalty' ? item.width : 0);\n const shrink = shrinks[b] - shrinks[start], stretch = stretches[b] - stretches[start] + emergency;\n const difference = lineWidth(a.line) - natural;\n const fil = infinite[b] > infinite[start];\n const badness = difference < -shrink ? 10001 : difference > 0 && fil ? 0 : texBadness(difference, difference > 0 ? stretch : shrink);\n const fitness = difference < 0 ? badness > 12 ? 0 : 1 : badness > 99 ? 3 : badness > 12 ? 2 : 1;\n const penalty = item.type === 'penalty' ? item.penalty : 0;\n const flagged = item.type === 'penalty' && !!item.flagged;\n let cost = Math.min(10000, Math.abs(linePenalty + badness)) ** 2;\n if (penalty >= 0) cost += penalty * penalty;\n else if (penalty > -10000) cost -= penalty * penalty;\n if (a.flagged && b === n - 1) cost += options.finalHyphenDemerits ?? 5000;\n else if (a.flagged && flagged) cost += options.doubleHyphenDemerits ?? 10000;\n if (Math.abs(fitness - a.fitness) > 1) cost += adjacent;\n const outputRatio = difference === 0 || difference > 0 && fil ? 0 : difference / (difference > 0 ? stretches[b] - stretches[start] : shrink);\n const candidate: Active = { at: b, start: next[Math.min(n, b + 1)], line: a.line + 1, fitness, flagged, demerits: a.demerits + cost, ratio: Number.isFinite(outputRatio) ? Math.max(-1, outputRatio) : 0, previous: a };\n if (badness <= threshold) {\n const key = (looseness ? candidate.line : varying ? Math.min(candidate.line, lengths.length - 1) : 0) * 4 + fitness;\n if (!best.has(key) || best.get(key)!.demerits > candidate.demerits) best.set(key, candidate);\n }\n if (!fallback || candidate.demerits < fallback.demerits) fallback = candidate;\n // Exclude this penalty's optional width: a later break may omit it.\n if (!forced && (!monotonic || widths[b] - widths[start] - shrink <= lineWidth(a.line))) survivors.push(a);\n }\n if (final && !best.size && !survivors.length && fallback) {\n // TeX's final pass preserves an otherwise impossible paragraph with an\n // artificial break; an indivisible overfull box stays visible.\n fallback.demerits = fallback.previous!.demerits;\n best.set(fallback.fitness, fallback);\n }\n active = [...survivors, ...best.values()];\n if (!active.length) return;\n }\n const endings = active.filter(a => a.at === n - 1);\n const best = endings.reduce<Active | undefined>((best, a) => !best || a.demerits < best.demerits ? a : best, undefined);\n if (!best || !looseness) return best;\n const desired = best.line + looseness;\n const chosen = endings.reduce((chosen, a) => Math.abs(a.line - desired) < Math.abs(chosen.line - desired) || Math.abs(a.line - desired) === Math.abs(chosen.line - desired) && a.demerits < chosen.demerits ? a : chosen, best);\n return final || chosen.line === desired ? chosen : undefined;\n };\n const emergency = options.emergencyStretch ?? 16;\n const passes = [\n { name: 'pretolerance', threshold: options.pretolerance ?? 100, hyphens: false, emergency: 0, final: false },\n { name: 'tolerance', threshold: options.tolerance ?? 200, hyphens: true, emergency: 0, final: emergency <= 0 },\n { name: 'emergency', threshold: options.tolerance ?? 200, hyphens: true, emergency, final: true },\n ] as const;\n for (const attempt of passes) {\n if (attempt.threshold < 0 || attempt.name === 'emergency' && !attempt.emergency) continue;\n const result = pass(Math.min(10000, attempt.threshold), attempt.hyphens, attempt.emergency, attempt.final);\n if (!result) continue;\n const lines: LineBreak[] = [];\n for (let at = result; at.previous; at = at.previous) lines.push({ index: at.at, start: at.previous.start, ratio: at.ratio, fitness: at.fitness });\n return { lines: lines.reverse(), demerits: result.demerits, pass: attempt.name };\n }\n return { lines: [], demerits: Infinity, pass: 'final' };\n };\n}\n"],"mappings":"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","names":["emergency","best","chosen"]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-FSI5OTBW.js.map