dsh-better-display 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/DESIGN.md +72 -0
- package/LICENSE +24 -0
- package/README.en.md +41 -0
- package/README.md +41 -0
- package/THIRD_PARTY_NOTICES.md +65 -0
- package/cordis.patch.yml +5 -0
- package/cordis.yml +4 -0
- package/dshx.yml +5 -0
- package/lib/client.js +49923 -0
- package/lib/client.js.map +1 -0
- package/lib/dsh-better-display.js +256 -0
- package/lib/types/client/Blocks.d.ts +45 -0
- package/lib/types/client/Blocks.d.ts.map +1 -0
- package/lib/types/client/Blocks.js +136 -0
- package/lib/types/client/Blocks.js.map +1 -0
- package/lib/types/client/ChoreographedFlow.d.ts +22 -0
- package/lib/types/client/ChoreographedFlow.d.ts.map +1 -0
- package/lib/types/client/ChoreographedFlow.js +170 -0
- package/lib/types/client/ChoreographedFlow.js.map +1 -0
- package/lib/types/client/ClosedProcessSummary.d.ts +9 -0
- package/lib/types/client/ClosedProcessSummary.d.ts.map +1 -0
- package/lib/types/client/ClosedProcessSummary.js +15 -0
- package/lib/types/client/ClosedProcessSummary.js.map +1 -0
- package/lib/types/client/LiveFold.d.ts +10 -0
- package/lib/types/client/LiveFold.d.ts.map +1 -0
- package/lib/types/client/LiveFold.js +39 -0
- package/lib/types/client/LiveFold.js.map +1 -0
- package/lib/types/client/McpAppFrame.d.ts +32 -0
- package/lib/types/client/McpAppFrame.d.ts.map +1 -0
- package/lib/types/client/McpAppFrame.js +193 -0
- package/lib/types/client/McpAppFrame.js.map +1 -0
- package/lib/types/client/Reader.d.ts +3 -0
- package/lib/types/client/Reader.d.ts.map +1 -0
- package/lib/types/client/Reader.js +537 -0
- package/lib/types/client/Reader.js.map +1 -0
- package/lib/types/client/ReasoningCard.d.ts +11 -0
- package/lib/types/client/ReasoningCard.d.ts.map +1 -0
- package/lib/types/client/ReasoningCard.js +301 -0
- package/lib/types/client/ReasoningCard.js.map +1 -0
- package/lib/types/client/StickyLane.d.ts +8 -0
- package/lib/types/client/StickyLane.d.ts.map +1 -0
- package/lib/types/client/StickyLane.js +28 -0
- package/lib/types/client/StickyLane.js.map +1 -0
- package/lib/types/client/TimelineRail.d.ts +10 -0
- package/lib/types/client/TimelineRail.d.ts.map +1 -0
- package/lib/types/client/TimelineRail.js +168 -0
- package/lib/types/client/TimelineRail.js.map +1 -0
- package/lib/types/client/ToolActivity.d.ts +17 -0
- package/lib/types/client/ToolActivity.d.ts.map +1 -0
- package/lib/types/client/ToolActivity.js +192 -0
- package/lib/types/client/ToolActivity.js.map +1 -0
- package/lib/types/client/TurnMetrics.d.ts +11 -0
- package/lib/types/client/TurnMetrics.d.ts.map +1 -0
- package/lib/types/client/TurnMetrics.js +44 -0
- package/lib/types/client/TurnMetrics.js.map +1 -0
- package/lib/types/client/WaitingStatus.d.ts +6 -0
- package/lib/types/client/WaitingStatus.d.ts.map +1 -0
- package/lib/types/client/WaitingStatus.js +19 -0
- package/lib/types/client/WaitingStatus.js.map +1 -0
- package/lib/types/client/conversation-scroll.d.ts +19 -0
- package/lib/types/client/conversation-scroll.d.ts.map +1 -0
- package/lib/types/client/conversation-scroll.js +25 -0
- package/lib/types/client/conversation-scroll.js.map +1 -0
- package/lib/types/client/deliverables.d.ts +24 -0
- package/lib/types/client/deliverables.d.ts.map +1 -0
- package/lib/types/client/deliverables.js +104 -0
- package/lib/types/client/deliverables.js.map +1 -0
- package/lib/types/client/entry-policy.d.ts +10 -0
- package/lib/types/client/entry-policy.d.ts.map +1 -0
- package/lib/types/client/entry-policy.js +24 -0
- package/lib/types/client/entry-policy.js.map +1 -0
- package/lib/types/client/entry.d.ts +4 -0
- package/lib/types/client/entry.d.ts.map +1 -0
- package/lib/types/client/entry.js +34 -0
- package/lib/types/client/entry.js.map +1 -0
- package/lib/types/client/fold-choreography.d.ts +28 -0
- package/lib/types/client/fold-choreography.d.ts.map +1 -0
- package/lib/types/client/fold-choreography.js +31 -0
- package/lib/types/client/fold-choreography.js.map +1 -0
- package/lib/types/client/index.d.ts +7 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/index.js +153 -0
- package/lib/types/client/index.js.map +1 -0
- package/lib/types/client/live-turn.d.ts +58 -0
- package/lib/types/client/live-turn.d.ts.map +1 -0
- package/lib/types/client/live-turn.js +144 -0
- package/lib/types/client/live-turn.js.map +1 -0
- package/lib/types/client/markdown/MarkdownText.d.ts +39 -0
- package/lib/types/client/markdown/MarkdownText.d.ts.map +1 -0
- package/lib/types/client/markdown/MarkdownText.js +171 -0
- package/lib/types/client/markdown/MarkdownText.js.map +1 -0
- package/lib/types/client/markdown/cjkFriendlyStrong.d.ts +9 -0
- package/lib/types/client/markdown/cjkFriendlyStrong.d.ts.map +1 -0
- package/lib/types/client/markdown/cjkFriendlyStrong.js +73 -0
- package/lib/types/client/markdown/cjkFriendlyStrong.js.map +1 -0
- package/lib/types/client/markdown/incremental.d.ts +69 -0
- package/lib/types/client/markdown/incremental.d.ts.map +1 -0
- package/lib/types/client/markdown/incremental.js +108 -0
- package/lib/types/client/markdown/incremental.js.map +1 -0
- package/lib/types/client/markdown/katex.d.ts +27 -0
- package/lib/types/client/markdown/katex.d.ts.map +1 -0
- package/lib/types/client/markdown/katex.js +88 -0
- package/lib/types/client/markdown/katex.js.map +1 -0
- package/lib/types/client/markdown/mathCompatibility.d.ts +11 -0
- package/lib/types/client/markdown/mathCompatibility.d.ts.map +1 -0
- package/lib/types/client/markdown/mathCompatibility.js +293 -0
- package/lib/types/client/markdown/mathCompatibility.js.map +1 -0
- package/lib/types/client/markdown/parse.d.ts +25 -0
- package/lib/types/client/markdown/parse.d.ts.map +1 -0
- package/lib/types/client/markdown/parse.js +42 -0
- package/lib/types/client/markdown/parse.js.map +1 -0
- package/lib/types/client/markdown/render.d.ts +119 -0
- package/lib/types/client/markdown/render.d.ts.map +1 -0
- package/lib/types/client/markdown/render.js +435 -0
- package/lib/types/client/markdown/render.js.map +1 -0
- package/lib/types/client/mcp-app.d.ts +50 -0
- package/lib/types/client/mcp-app.d.ts.map +1 -0
- package/lib/types/client/mcp-app.js +328 -0
- package/lib/types/client/mcp-app.js.map +1 -0
- package/lib/types/client/message-chrome.d.ts +19 -0
- package/lib/types/client/message-chrome.d.ts.map +1 -0
- package/lib/types/client/message-chrome.js +42 -0
- package/lib/types/client/message-chrome.js.map +1 -0
- package/lib/types/client/motion.d.ts +38 -0
- package/lib/types/client/motion.d.ts.map +1 -0
- package/lib/types/client/motion.js +367 -0
- package/lib/types/client/motion.js.map +1 -0
- package/lib/types/client/native/ContextBody.d.ts +130 -0
- package/lib/types/client/native/ContextBody.d.ts.map +1 -0
- package/lib/types/client/native/ContextBody.js +398 -0
- package/lib/types/client/native/ContextBody.js.map +1 -0
- package/lib/types/client/native/ContextInjectionRow.d.ts +26 -0
- package/lib/types/client/native/ContextInjectionRow.d.ts.map +1 -0
- package/lib/types/client/native/ContextInjectionRow.js +27 -0
- package/lib/types/client/native/ContextInjectionRow.js.map +1 -0
- package/lib/types/client/native/ReferenceIcon.d.ts +16 -0
- package/lib/types/client/native/ReferenceIcon.d.ts.map +1 -0
- package/lib/types/client/native/ReferenceIcon.js +16 -0
- package/lib/types/client/native/ReferenceIcon.js.map +1 -0
- package/lib/types/client/native/tool-call-model.d.ts +58 -0
- package/lib/types/client/native/tool-call-model.d.ts.map +1 -0
- package/lib/types/client/native/tool-call-model.js +219 -0
- package/lib/types/client/native/tool-call-model.js.map +1 -0
- package/lib/types/client/open-file.d.ts +24 -0
- package/lib/types/client/primitive-labels.d.ts +10 -0
- package/lib/types/client/primitive-labels.d.ts.map +1 -0
- package/lib/types/client/primitive-labels.js +37 -0
- package/lib/types/client/primitive-labels.js.map +1 -0
- package/lib/types/client/projection.d.ts +41 -0
- package/lib/types/client/projection.d.ts.map +1 -0
- package/lib/types/client/projection.js +112 -0
- package/lib/types/client/projection.js.map +1 -0
- package/lib/types/client/reasoning-follow.d.ts +6 -0
- package/lib/types/client/reasoning-follow.d.ts.map +1 -0
- package/lib/types/client/reasoning-follow.js +12 -0
- package/lib/types/client/reasoning-follow.js.map +1 -0
- package/lib/types/client/settings-copy.d.ts +6 -0
- package/lib/types/client/settings-slots.d.ts +16 -0
- package/lib/types/client/store.d.ts +17 -0
- package/lib/types/client/store.d.ts.map +1 -0
- package/lib/types/client/store.js +13 -0
- package/lib/types/client/store.js.map +1 -0
- package/lib/types/client/stream-buffer.d.ts +29 -0
- package/lib/types/client/stream-buffer.d.ts.map +1 -0
- package/lib/types/client/stream-buffer.js +113 -0
- package/lib/types/client/stream-buffer.js.map +1 -0
- package/lib/types/client/streaming.d.ts +18 -0
- package/lib/types/client/streaming.d.ts.map +1 -0
- package/lib/types/client/streaming.js +77 -0
- package/lib/types/client/streaming.js.map +1 -0
- package/lib/types/client/timeline.d.ts +26 -0
- package/lib/types/client/timeline.d.ts.map +1 -0
- package/lib/types/client/timeline.js +48 -0
- package/lib/types/client/timeline.js.map +1 -0
- package/lib/types/client/tool-activity.d.ts +52 -0
- package/lib/types/client/tool-activity.d.ts.map +1 -0
- package/lib/types/client/tool-activity.js +178 -0
- package/lib/types/client/tool-activity.js.map +1 -0
- package/lib/types/client/types.d.ts +66 -0
- package/lib/types/client/types.d.ts.map +1 -0
- package/lib/types/client/types.js +2 -0
- package/lib/types/client/types.js.map +1 -0
- package/lib/types/client/waiting-clock.d.ts +17 -0
- package/lib/types/client/waiting-clock.d.ts.map +1 -0
- package/lib/types/client/waiting-clock.js +24 -0
- package/lib/types/client/waiting-clock.js.map +1 -0
- package/lib/types/client/word-motion.d.ts +16 -0
- package/lib/types/client/word-motion.d.ts.map +1 -0
- package/lib/types/client/word-motion.js +89 -0
- package/lib/types/client/word-motion.js.map +1 -0
- package/lib/types/client/word-timeline.d.ts +28 -0
- package/lib/types/client/word-timeline.d.ts.map +1 -0
- package/lib/types/client/word-timeline.js +100 -0
- package/lib/types/client/word-timeline.js.map +1 -0
- package/lib/types/dsh-better-display.d.ts +17 -0
- package/lib/types/dsh-better-display.d.ts.map +1 -0
- package/lib/types/dsh-better-display.js +53 -0
- package/lib/types/dsh-better-display.js.map +1 -0
- package/package.json +121 -0
- package/scripts/build-motion-fixture.mjs +26 -0
- package/scripts/link-harness-dependencies.mjs +51 -0
- package/skills/generative-mcpapps/SKILL.md +47 -0
- package/skills/generative-mcpapps/examples/interactive_quiz.html +153 -0
- package/skills/generative-mcpapps/references/html_boilerplate.md +122 -0
- package/skills/generative-mcpapps/references/sep1865_protocol.md +54 -0
- package/src/client/Blocks.tsx +205 -0
- package/src/client/ChoreographedFlow.tsx +182 -0
- package/src/client/ClosedProcessSummary.tsx +19 -0
- package/src/client/LiveFold.tsx +43 -0
- package/src/client/McpAppFrame.module.css +210 -0
- package/src/client/McpAppFrame.tsx +317 -0
- package/src/client/Reader.module.css +329 -0
- package/src/client/Reader.tsx +814 -0
- package/src/client/ReasoningCard.tsx +285 -0
- package/src/client/SettingsSection.module.css +147 -0
- package/src/client/SettingsSection.tsx +117 -0
- package/src/client/StickyLane.tsx +24 -0
- package/src/client/TimelineRail.module.css +170 -0
- package/src/client/TimelineRail.tsx +262 -0
- package/src/client/ToolActivity.tsx +214 -0
- package/src/client/TurnMetrics.module.css +139 -0
- package/src/client/TurnMetrics.tsx +160 -0
- package/src/client/WaitingStatus.tsx +22 -0
- package/src/client/conversation-scroll.ts +28 -0
- package/src/client/deliverables.ts +122 -0
- package/src/client/entry-policy.ts +20 -0
- package/src/client/entry.tsx +40 -0
- package/src/client/fold-choreography.ts +38 -0
- package/src/client/index.tsx +198 -0
- package/src/client/live-turn.ts +155 -0
- package/src/client/markdown/MarkdownText.module.css +304 -0
- package/src/client/markdown/MarkdownText.tsx +187 -0
- package/src/client/markdown/cjkFriendlyStrong.ts +84 -0
- package/src/client/markdown/incremental.ts +131 -0
- package/src/client/markdown/katex.tsx +91 -0
- package/src/client/markdown/mathCompatibility.ts +350 -0
- package/src/client/markdown/parse.ts +45 -0
- package/src/client/markdown/render.tsx +630 -0
- package/src/client/markdown/upstream.json +14 -0
- package/src/client/mcp-app.ts +323 -0
- package/src/client/message-chrome.ts +47 -0
- package/src/client/motion.tsx +338 -0
- package/src/client/native/ContextBody.module.css +161 -0
- package/src/client/native/ContextBody.tsx +591 -0
- package/src/client/native/ContextInjectionRow.module.css +62 -0
- package/src/client/native/ContextInjectionRow.tsx +72 -0
- package/src/client/native/ReferenceIcon.tsx +35 -0
- package/src/client/native/tool-call-model.ts +248 -0
- package/src/client/native/upstream.json +41 -0
- package/src/client/open-file.ts +94 -0
- package/src/client/pending-submission.ts +49 -0
- package/src/client/primitive-labels.ts +53 -0
- package/src/client/projection.ts +118 -0
- package/src/client/reasoning-follow.ts +12 -0
- package/src/client/settings-copy.ts +53 -0
- package/src/client/settings-slots.ts +20 -0
- package/src/client/settings.tsx +73 -0
- package/src/client/skill-status.ts +78 -0
- package/src/client/store.ts +30 -0
- package/src/client/stream-buffer.ts +100 -0
- package/src/client/streaming.tsx +62 -0
- package/src/client/style.d.ts +4 -0
- package/src/client/timeline.ts +77 -0
- package/src/client/tool-activity.ts +152 -0
- package/src/client/types.ts +66 -0
- package/src/client/waiting-clock.ts +25 -0
- package/src/client/word-motion.tsx +91 -0
- package/src/client/word-timeline.ts +96 -0
- package/src/dsh-better-display.ts +108 -0
- package/src/skill-roots.ts +138 -0
- package/src/skill-status.ts +81 -0
- package/tests/browser-closed-gap.tsx +20 -0
- package/tests/browser-motion.tsx +65 -0
- package/tests/browser-sticky-lanes.tsx +22 -0
- package/tests/browser-waiting-clock.tsx +14 -0
- package/tests/chat-flow-hook.test.ts +66 -0
- package/tests/cloud-gate.test.ts +34 -0
- package/tests/conversation-scroll.test.ts +47 -0
- package/tests/deliverables.test.ts +128 -0
- package/tests/entry.test.ts +42 -0
- package/tests/fixtures/maid-composer-hide.html +31 -0
- package/tests/fold-choreography.test.ts +38 -0
- package/tests/history-word-regression.test.ts +16 -0
- package/tests/live-turn.test.ts +218 -0
- package/tests/mcp-apps.test.ts +157 -0
- package/tests/message-chrome.test.ts +29 -0
- package/tests/open-file.test.ts +103 -0
- package/tests/pending-submission.test.ts +45 -0
- package/tests/projection.test.ts +184 -0
- package/tests/reasoning-follow.test.ts +34 -0
- package/tests/settings-copy.test.ts +63 -0
- package/tests/skill-status.test.ts +137 -0
- package/tests/stock-install.test.ts +50 -0
- package/tests/stream-buffer.test.ts +97 -0
- package/tests/timeline.test.ts +59 -0
- package/tests/waiting-clock.test.ts +24 -0
- package/tests/word-timeline.test.ts +136 -0
- package/tsconfig.json +11 -0
- package/tsdown.config.ts +49 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
// Adapted from DeepSeek Harness b150a551b8d465e31e418e1b2eaf5e79bbb7d28e (MIT). See THIRD_PARTY_NOTICES.md.
|
|
2
|
+
/** Extend upstream dollar-only math syntax with TeX delimiters while reusing its token vocabulary. */
|
|
3
|
+
|
|
4
|
+
import { factorySpace } from 'micromark-factory-space'
|
|
5
|
+
import type {} from 'micromark-extension-math'
|
|
6
|
+
import { markdownLineEnding } from 'micromark-util-character'
|
|
7
|
+
import { codes, constants, types } from 'micromark-util-symbol'
|
|
8
|
+
import type { Construct, Extension, Previous, State, Tokenizer } from 'micromark-util-types'
|
|
9
|
+
|
|
10
|
+
// oxlint-disable typescript/no-this-alias -- micromark binds tokenizer context only on the outer callback.
|
|
11
|
+
|
|
12
|
+
const previousBackslash: Previous = function (code) {
|
|
13
|
+
if (code !== codes.backslash) return true
|
|
14
|
+
const tail = this.events.at(-1)
|
|
15
|
+
/* v8 ignore next -- a previous code necessarily has a preceding event. */
|
|
16
|
+
if (tail === undefined) return false
|
|
17
|
+
return tail[1].type === types.characterEscape
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const tokenizeBackslashMathText: Tokenizer = function (effects, ok, nok) {
|
|
21
|
+
return start
|
|
22
|
+
|
|
23
|
+
function start(code: number | null): State | undefined {
|
|
24
|
+
/* v8 ignore next -- the text construct is dispatched only for a backslash. */
|
|
25
|
+
if (code !== codes.backslash) return nok(code)
|
|
26
|
+
effects.enter('mathText')
|
|
27
|
+
effects.enter('mathTextSequence')
|
|
28
|
+
effects.consume(code)
|
|
29
|
+
return open
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function open(code: number | null): State | undefined {
|
|
33
|
+
if (code !== codes.leftParenthesis) return nok(code)
|
|
34
|
+
effects.consume(code)
|
|
35
|
+
effects.exit('mathTextSequence')
|
|
36
|
+
return between
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function between(code: number | null): State | undefined {
|
|
40
|
+
if (code === codes.eof) return nok(code)
|
|
41
|
+
if (code === codes.backslash) {
|
|
42
|
+
return effects.attempt({ partial: true, tokenize: tokenizeClose }, close, afterCloseAttempt)(code)
|
|
43
|
+
}
|
|
44
|
+
if (markdownLineEnding(code)) {
|
|
45
|
+
effects.enter(types.lineEnding)
|
|
46
|
+
effects.consume(code)
|
|
47
|
+
effects.exit(types.lineEnding)
|
|
48
|
+
return between
|
|
49
|
+
}
|
|
50
|
+
return dataStart(code)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function afterCloseAttempt(code: number | null): State | undefined {
|
|
54
|
+
return effects.check({ partial: true, tokenize: tokenizeOpen }, nok, dataStart)(code)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function dataStart(code: number | null): State | undefined {
|
|
58
|
+
effects.enter('mathTextData')
|
|
59
|
+
effects.consume(code)
|
|
60
|
+
return code === codes.backslash ? afterDataBackslash : data
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function afterDataBackslash(code: number | null): State | undefined {
|
|
64
|
+
if (code === codes.backslash) {
|
|
65
|
+
effects.consume(code)
|
|
66
|
+
return data
|
|
67
|
+
}
|
|
68
|
+
return data(code)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function data(code: number | null): State | undefined {
|
|
72
|
+
if (code === codes.eof || code === codes.backslash || markdownLineEnding(code)) {
|
|
73
|
+
effects.exit('mathTextData')
|
|
74
|
+
return between(code)
|
|
75
|
+
}
|
|
76
|
+
effects.consume(code)
|
|
77
|
+
return data
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function close(code: number | null): State | undefined {
|
|
81
|
+
effects.exit('mathText')
|
|
82
|
+
return ok(code)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function tokenizeClose(closeEffects: Parameters<Tokenizer>[0], closeOk: State, closeNok: State): State {
|
|
86
|
+
return slash
|
|
87
|
+
|
|
88
|
+
function slash(code: number | null): State | undefined {
|
|
89
|
+
/* v8 ignore next -- this partial construct is attempted only at a backslash. */
|
|
90
|
+
if (code !== codes.backslash) return closeNok(code)
|
|
91
|
+
closeEffects.enter('mathTextSequence')
|
|
92
|
+
closeEffects.consume(code)
|
|
93
|
+
return parenthesis
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function parenthesis(code: number | null): State | undefined {
|
|
97
|
+
if (code !== codes.rightParenthesis) return closeNok(code)
|
|
98
|
+
closeEffects.consume(code)
|
|
99
|
+
closeEffects.exit('mathTextSequence')
|
|
100
|
+
return closeOk
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function tokenizeOpen(openEffects: Parameters<Tokenizer>[0], openOk: State, openNok: State): State {
|
|
105
|
+
return slash
|
|
106
|
+
|
|
107
|
+
function slash(code: number | null): State | undefined {
|
|
108
|
+
/* v8 ignore next -- the opening check follows a failed close attempt at a backslash. */
|
|
109
|
+
if (code !== codes.backslash) return openNok(code)
|
|
110
|
+
openEffects.enter(types.chunkString)
|
|
111
|
+
openEffects.consume(code)
|
|
112
|
+
return parenthesis
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function parenthesis(code: number | null): State | undefined {
|
|
116
|
+
if (code !== codes.leftParenthesis) return openNok(code)
|
|
117
|
+
openEffects.consume(code)
|
|
118
|
+
openEffects.exit(types.chunkString)
|
|
119
|
+
return openOk
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function createMathFlow(marker: number, openMarker: number, closeMarker: number, multiline: boolean): Construct {
|
|
125
|
+
const tokenize: Tokenizer = function (effects, ok, nok) {
|
|
126
|
+
const self = this
|
|
127
|
+
let oddBackslashRun = false
|
|
128
|
+
const tail = self.events.at(-1)
|
|
129
|
+
const initialSize = tail?.[1].type === types.linePrefix
|
|
130
|
+
? tail[2].sliceSerialize(tail[1], true).length
|
|
131
|
+
: 0
|
|
132
|
+
|
|
133
|
+
return start
|
|
134
|
+
|
|
135
|
+
function start(code: number | null): State | undefined {
|
|
136
|
+
/* v8 ignore next -- the flow construct is dispatched only for its marker. */
|
|
137
|
+
if (code !== marker) return nok(code)
|
|
138
|
+
effects.enter('mathFlow')
|
|
139
|
+
effects.enter('mathFlowFence')
|
|
140
|
+
effects.enter('mathFlowFenceSequence')
|
|
141
|
+
effects.consume(code)
|
|
142
|
+
return open
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function open(code: number | null): State | undefined {
|
|
146
|
+
if (code !== openMarker) return nok(code)
|
|
147
|
+
effects.consume(code)
|
|
148
|
+
effects.exit('mathFlowFenceSequence')
|
|
149
|
+
effects.exit('mathFlowFence')
|
|
150
|
+
return marker === codes.dollarSign ? afterDollarOpen : content
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function afterDollarOpen(code: number | null): State | undefined {
|
|
154
|
+
return code === codes.dollarSign ? nok(code) : content(code)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function content(code: number | null): State | undefined {
|
|
158
|
+
if (code === codes.eof) return nok(code)
|
|
159
|
+
if (code === marker && (marker !== codes.dollarSign || !oddBackslashRun)) {
|
|
160
|
+
return effects.attempt(
|
|
161
|
+
{ partial: true, tokenize: tokenizeClosingFence },
|
|
162
|
+
closed,
|
|
163
|
+
afterClosingFenceAttempt,
|
|
164
|
+
)(code)
|
|
165
|
+
}
|
|
166
|
+
if (markdownLineEnding(code)) {
|
|
167
|
+
return multiline
|
|
168
|
+
? effects.attempt(nonLazyContinuation, afterContinuation, nok)(code)
|
|
169
|
+
: nok(code)
|
|
170
|
+
}
|
|
171
|
+
return valueStart(code)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function afterClosingFenceAttempt(code: number | null): State | undefined {
|
|
175
|
+
return marker === codes.backslash
|
|
176
|
+
? effects.check({ partial: true, tokenize: tokenizeOpeningFence }, nok, markerValueStart)(code)
|
|
177
|
+
: markerValueStart(code)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function afterContinuation(code: number | null): State | undefined {
|
|
181
|
+
return effects.attempt(
|
|
182
|
+
{ partial: true, tokenize: tokenizeClosingFence },
|
|
183
|
+
closed,
|
|
184
|
+
initialSize
|
|
185
|
+
? factorySpace(effects, content, types.linePrefix, initialSize + 1)
|
|
186
|
+
: content,
|
|
187
|
+
)(code)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function valueStart(code: number | null): State | undefined {
|
|
191
|
+
effects.enter('mathFlowValue')
|
|
192
|
+
oddBackslashRun = code === codes.backslash
|
|
193
|
+
effects.consume(code)
|
|
194
|
+
return value
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function markerValueStart(code: number | null): State | undefined {
|
|
198
|
+
effects.enter('mathFlowValue')
|
|
199
|
+
oddBackslashRun = false
|
|
200
|
+
effects.consume(code)
|
|
201
|
+
return valueAfterMarker
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function valueAfterMarker(code: number | null): State | undefined {
|
|
205
|
+
if (code === marker) {
|
|
206
|
+
effects.consume(code)
|
|
207
|
+
return value
|
|
208
|
+
}
|
|
209
|
+
return value(code)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function value(code: number | null): State | undefined {
|
|
213
|
+
if (code === codes.eof || code === marker || markdownLineEnding(code)) {
|
|
214
|
+
effects.exit('mathFlowValue')
|
|
215
|
+
return content(code)
|
|
216
|
+
}
|
|
217
|
+
oddBackslashRun = code === codes.backslash ? !oddBackslashRun : false
|
|
218
|
+
effects.consume(code)
|
|
219
|
+
return value
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function closed(code: number | null): State | undefined {
|
|
223
|
+
effects.exit('mathFlow')
|
|
224
|
+
return ok(code)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function tokenizeClosingFence(
|
|
228
|
+
closeEffects: Parameters<Tokenizer>[0],
|
|
229
|
+
closeOk: State,
|
|
230
|
+
closeNok: State,
|
|
231
|
+
): State {
|
|
232
|
+
return factorySpace(closeEffects, sequenceStart, types.linePrefix, constants.tabSize)
|
|
233
|
+
|
|
234
|
+
function sequenceStart(code: number | null): State | undefined {
|
|
235
|
+
if (code !== marker) return closeNok(code)
|
|
236
|
+
closeEffects.enter('mathFlowFence')
|
|
237
|
+
closeEffects.enter('mathFlowFenceSequence')
|
|
238
|
+
closeEffects.consume(code)
|
|
239
|
+
return sequenceEnd
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function sequenceEnd(code: number | null): State | undefined {
|
|
243
|
+
if (code !== closeMarker) return closeNok(code)
|
|
244
|
+
closeEffects.consume(code)
|
|
245
|
+
closeEffects.exit('mathFlowFenceSequence')
|
|
246
|
+
return factorySpace(closeEffects, after, types.whitespace)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function after(code: number | null): State | undefined {
|
|
250
|
+
if (code !== codes.eof && !markdownLineEnding(code)) return closeNok(code)
|
|
251
|
+
closeEffects.exit('mathFlowFence')
|
|
252
|
+
return closeOk(code)
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function tokenizeOpeningFence(
|
|
257
|
+
openEffects: Parameters<Tokenizer>[0],
|
|
258
|
+
openOk: State,
|
|
259
|
+
openNok: State,
|
|
260
|
+
): State {
|
|
261
|
+
return sequenceStart
|
|
262
|
+
|
|
263
|
+
function sequenceStart(code: number | null): State | undefined {
|
|
264
|
+
/* v8 ignore next -- the opening check follows a failed close attempt at the marker. */
|
|
265
|
+
if (code !== marker) return openNok(code)
|
|
266
|
+
openEffects.enter(types.chunkString)
|
|
267
|
+
openEffects.consume(code)
|
|
268
|
+
return sequenceEnd
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function sequenceEnd(code: number | null): State | undefined {
|
|
272
|
+
if (code !== openMarker) return openNok(code)
|
|
273
|
+
openEffects.consume(code)
|
|
274
|
+
openEffects.exit(types.chunkString)
|
|
275
|
+
return openOk
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return {
|
|
281
|
+
concrete: true,
|
|
282
|
+
name: marker === codes.dollarSign ? 'sameLineDollarMathFlow' : 'backslashMathFlow',
|
|
283
|
+
tokenize,
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const tokenizeNonLazyContinuation: Tokenizer = function (effects, ok, nok) {
|
|
288
|
+
const self = this
|
|
289
|
+
|
|
290
|
+
return start
|
|
291
|
+
|
|
292
|
+
function start(code: number | null): State | undefined {
|
|
293
|
+
/* v8 ignore next -- continuation constructs are attempted only after a line ending. */
|
|
294
|
+
if (code === codes.eof) return ok(code)
|
|
295
|
+
/* v8 ignore next -- continuation constructs are attempted only after a line ending. */
|
|
296
|
+
if (!markdownLineEnding(code)) return nok(code)
|
|
297
|
+
effects.enter(types.lineEnding)
|
|
298
|
+
effects.consume(code)
|
|
299
|
+
effects.exit(types.lineEnding)
|
|
300
|
+
return lineStart
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function lineStart(code: number | null): State | undefined {
|
|
304
|
+
return self.parser.lazy[self.now().line] ? nok(code) : ok(code)
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const nonLazyContinuation: Construct = {
|
|
309
|
+
partial: true,
|
|
310
|
+
tokenize: tokenizeNonLazyContinuation,
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const backslashMathText: Construct = {
|
|
314
|
+
name: 'backslashMathText',
|
|
315
|
+
previous: previousBackslash,
|
|
316
|
+
tokenize: tokenizeBackslashMathText,
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const backslashMathFlow = createMathFlow(
|
|
320
|
+
codes.backslash,
|
|
321
|
+
codes.leftSquareBracket,
|
|
322
|
+
codes.rightSquareBracket,
|
|
323
|
+
true,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
const sameLineDollarMathFlow = createMathFlow(
|
|
327
|
+
codes.dollarSign,
|
|
328
|
+
codes.dollarSign,
|
|
329
|
+
codes.dollarSign,
|
|
330
|
+
false,
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
const backslashMath: Extension = {
|
|
334
|
+
flow: {
|
|
335
|
+
[codes.backslash]: backslashMathFlow,
|
|
336
|
+
[codes.dollarSign]: sameLineDollarMathFlow,
|
|
337
|
+
},
|
|
338
|
+
text: { [codes.backslash]: backslashMathText },
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* TeX backslash delimiters and same-line display-dollar blocks as a micromark
|
|
343
|
+
* syntax extension reusing `micromark-extension-math`'s token vocabulary; the
|
|
344
|
+
* caller must also register `math()` on the same parse so the emitted tokens
|
|
345
|
+
* compile to standard math nodes.
|
|
346
|
+
* @returns The micromark syntax extension.
|
|
347
|
+
*/
|
|
348
|
+
export function mathCompatibility(): Extension {
|
|
349
|
+
return backslashMath
|
|
350
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Adapted from DeepSeek Harness b150a551b8d465e31e418e1b2eaf5e79bbb7d28e (MIT). See THIRD_PARTY_NOTICES.md.
|
|
2
|
+
/**
|
|
3
|
+
* The markdown renderer's two mdast grammars, one per rendering arm. Each
|
|
4
|
+
* arm is internally consistent — the incremental tail parses, the one-shot
|
|
5
|
+
* parses, and the plain-text projection of a given grammar always agree on
|
|
6
|
+
* where blocks start and end — and the settled grammar is the streaming one
|
|
7
|
+
* plus the math extensions, so the arms differ only where TeX delimiters
|
|
8
|
+
* begin a math construct (a `$$` block is a paragraph while streaming and a
|
|
9
|
+
* math block once settled, by design).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Root } from 'mdast'
|
|
13
|
+
import { fromMarkdown } from 'mdast-util-from-markdown'
|
|
14
|
+
import { gfmFromMarkdown } from 'mdast-util-gfm'
|
|
15
|
+
import { mathFromMarkdown } from 'mdast-util-math'
|
|
16
|
+
import { gfm } from 'micromark-extension-gfm'
|
|
17
|
+
import { math } from 'micromark-extension-math'
|
|
18
|
+
import { cjkFriendlyStrong } from './cjkFriendlyStrong.js'
|
|
19
|
+
import { mathCompatibility } from './mathCompatibility.js'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Parse GFM markdown (the streaming arm's grammar: no math, so incomplete
|
|
23
|
+
* TeX never flashes KaTeX errors mid-stream).
|
|
24
|
+
* @param text - Markdown source.
|
|
25
|
+
* @returns The mdast root.
|
|
26
|
+
*/
|
|
27
|
+
export function parseGfm(text: string): Root {
|
|
28
|
+
return fromMarkdown(text, {
|
|
29
|
+
extensions: [gfm(), cjkFriendlyStrong()],
|
|
30
|
+
mdastExtensions: [gfmFromMarkdown()],
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parse GFM markdown plus TeX math with the compatibility delimiters
|
|
36
|
+
* (the settled arm's grammar).
|
|
37
|
+
* @param text - Markdown source.
|
|
38
|
+
* @returns The mdast root.
|
|
39
|
+
*/
|
|
40
|
+
export function parseGfmWithMath(text: string): Root {
|
|
41
|
+
return fromMarkdown(text, {
|
|
42
|
+
extensions: [gfm(), cjkFriendlyStrong(), mathCompatibility(), math()],
|
|
43
|
+
mdastExtensions: [gfmFromMarkdown(), mathFromMarkdown()],
|
|
44
|
+
})
|
|
45
|
+
}
|